//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	Smetask.c
//		SME task
//	history : 01/14/03' created 
//
//	Description:
//		(1)
//		(2)
//
//
//
//	Import msg: SMEMSG_SCAN_REQ			(from GUI or ROAM)
//				SMEMSG_SCAN_CFM			(from SCAN)
//				SMEMSG_START_IBSS		(from GUI)
//				SMEMSG_JOIN_REQ			(from GUI)
//				SMEMSG_HANDOVER_JOIN_REQ(from ROAM)
//				SMEMSG_TSF_SYNC_IND		(from interrupt)
//				SMEMSG_AUTHEN_REQ		(from GUI)
//				SMEMSG_AUTHEN_CFM		(from MLME)
//				SMEMSG_DEAUTHEN_REQ		(from GUI)
//				SMEMSG_DEAUTHEN_IND		(from MLME)
//				SMEMSG_ASSOC_REQ		(from GUI)
//				SMEMSG_ASSOC_CFM		(from MLME)
//				SMEMSG_DISASSOC_REQ		(from GUI)
//				SMEMSG_DISASSOC_IND		(from MLME)
//				SMEMSG_DISCONNECT_REQ	
//				SMEMSG_END_ROAMING		(from ROAM)
//				
//	Export msg:	SCANMSG_SCAN_REQ
//				MLMEMSG_AUTH_REQ
//				MLMEMSG_DEAUTH_REQ
//				MLMEMSG_ASSOC_REQ
//				MLMEMSG_REASSOC_REQ
//				ROAMMSG_ROAM_REQ
//				ROAMMSG_DEAUTHEN_IND
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "os_common.h"

#define SMEstate		(Adapter->sSmePara.wState)

// STATIC Function
//=================== Subroutine of SME Module
BOOL boJoinExistBSS(PWB32_ADAPTER Adapter, USHORT wFoundIndex);
BOOL boJoinNonExistBSS(PWB32_ADAPTER Adapter);
void ClearOldData(PWB32_ADAPTER Adapter);
BOOL boJoinAction(PWB32_ADAPTER Adapter);
void vActiveHWMAC_join(PWB32_ADAPTER Adapter);
void vActiveHWMAC_IBSS(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData);
void vNetConnectIndicate(PWB32_ADAPTER Adapter);
void vNetDisconnectInd(PWB32_ADAPTER Adapter);
void vSmeTimerStart(PWB32_ADAPTER Adapter, UINT timeout_value);
void vSmeTimerStop(PWB32_ADAPTER Adapter);
void vSmeTimerHandler_1a(IN PVOID	Data);
void vSmeTimerHandler(IN PVOID			SystemSpecific1,
					  IN PWB32_ADAPTER 	Adapter,
					  IN PVOID			SystemSpecific2,
					  IN PVOID			SystemSpecific3);
void TxRateHandler(PWB32_ADAPTER Adapter);

//=================== Action Function of SME Module
void vSmeProc_ScanReq(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_JoinReq(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_ScanCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_JoinActive(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_StartIBSSReq(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_StartIBSSActive(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_IbssStartCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_IbssAuth(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_JoinCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_JoinFail(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_AuthenReq(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_EssAuthenCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_AuthRetryTimeOut(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_AssocCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_AssocReq(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_Disconnect(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_ReScan(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_ScanThenJoin(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_BgScan(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_ManualHandoverJoin(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_HandoverJoin(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_EndRoaming(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_DeauthenInd(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_DisassocInd(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_PowerSaveReq(PWB32_ADAPTER Adapter,pK_MSG psMsg);
//void vSmeProc_IBSSJoinUpdateBSSID(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_CountermeaureCancel(PWB32_ADAPTER Adapter, pK_MSG psMsg);
void vSmeProc_CountermeasureBlockCancel(PWB32_ADAPTER Adapter, pK_MSG psMsg);

//========== Define the state machine table of SME module =================
static const K_TRANS asDisabled[] =
{
	{SMEMSG_SCAN_REQ,			vSmeProc_ScanReq					},
	{SMEMSG_START_IBSS,			vSmeProc_StartIBSSReq				},
	{SMEMSG_JOIN_REQ,			vSmeProc_JoinReq					},
	{K_NULL_MSG,				vProc_Null						}
};

static const K_TRANS asInit_Scan[] =
{
	{SMEMSG_START_IBSS,			vSmeProc_StartIBSSReq				},
	{SMEMSG_JOIN_REQ,			vSmeProc_JoinReq					},
	{SMEMSG_SCAN_CFM,			vSmeProc_ScanCfm					},
	{K_NULL_MSG,				vProc_Null						}
};

static const K_TRANS asScan_Ready[] =
{
	{SMEMSG_JOIN_REQ,			vSmeProc_JoinActive				},
	{SMEMSG_SCAN_REQ,			vSmeProc_ReScan					},
	{SMEMSG_SCAN_JOIN_REQ,		vSmeProc_ScanThenJoin			},
	{SMEMSG_START_IBSS,			vSmeProc_StartIBSSActive		},
	{SMEMSG_HANDOVER_JOIN_REQ,	vSmeProc_HandoverJoin			},
	{SMEMSG_END_ROAMING,		vSmeProc_EndRoaming				},
	{SMEMSG_SCAN_CFM,			vSmeProc_ScanCfm					},
	{SMEMSG_COUNTERMEASURE_BLOCK_TIMEOUT,	vSmeProc_CountermeasureBlockCancel	},
	{SMEMSG_POWERSAVE_REQ,		vSmeProc_PowerSaveReq			},
	{K_NULL_MSG,				vProc_Null						}
};

static const K_TRANS asStart_IBSS[] =
{
	{SMEMSG_START_IBSS_CFM,		vSmeProc_IbssStartCfm				},
	//{SMEMSG_TIMEOUT,			vSmeProc_IbssScanTimer				}, // In IBSS state, STA continue passive scan waiting Beacon
	//{SMEMSG_SCAN_REQ,			vSmeProc_IbssScanReq				}, // don't need extra timer to trigger scan action
	//TODO: following msg is marked at 12/27/03', it will accept the same join 
	//		request(same ssid) if XP launch same join request twice.
	{SMEMSG_JOIN_REQ,			vSmeProc_ManualHandoverJoin		},
	//{SMEMSG_IBSS_JOIN_UPDATE_BSSID, vSmeProc_IBSSJoinUpdateBSSID},
	{SMEMSG_SCAN_REQ,			vSmeProc_BgScan					},
	{K_NULL_MSG,				vProc_Null						}
};

static const K_TRANS asJoin_Pending[] =
{
	{SMEMSG_TSF_SYNC_IND,		vSmeProc_JoinCfm					},
	//{SMEMSG_START_IBSS_CFM,	vSmeProc_JoinCfm					},
	{SMEMSG_JOIN_REQ,			vSmeProc_ManualHandoverJoin		},
	{SMEMSG_TIMEOUT,			vSmeProc_JoinFail					},
	{SMEMSG_END_ROAMING,		vSmeProc_EndRoaming				},
	{K_NULL_MSG,				vProc_Null						}
};

static const K_TRANS asJoin_Cfm[]=
{
	{SMEMSG_AUTHEN_REQ,			vSmeProc_AuthenReq					},
	//{SMEMSG_TIMEOUT,			vSmeProc_IbssWaitAuthTimeout		},
	{K_NULL_MSG,				vProc_Null						}
};

static const K_TRANS asAuthenticate_Pending[] =
{
	{SMEMSG_AUTHEN_CFM,			vSmeProc_EssAuthenCfm			},
	{SMEMSG_TIMEOUT,			vSmeProc_AuthRetryTimeOut		},
	{K_NULL_MSG,				vProc_Null						}
};

static const K_TRANS asAuthenticated[] =
{
	{SMEMSG_ASSOC_CFM,			vSmeProc_AssocCfm				},
	{SMEMSG_ASSOC_REQ,			vSmeProc_AssocReq				},
	{SMEMSG_DEAUTHEN_IND,		vSmeProc_DeauthenInd			},
	//{SMEMSG_DISASSOC_IND,		vSmeProc_DisassocInd			},
	{SMEMSG_DISASSOC_IND,		vSmeProc_DeauthenInd			},
	{K_NULL_MSG,				vProc_Null						}
};

static const K_TRANS asConnected[] =
{
	{SMEMSG_DISCONNECT_REQ,		vSmeProc_Disconnect				},
	{SMEMSG_DEAUTHEN_REQ,		vSmeProc_Disconnect				},
	{SMEMSG_DISASSOC_REQ,		vSmeProc_Disconnect				},
	{SMEMSG_SCAN_REQ,			vSmeProc_BgScan					},
	{SMEMSG_JOIN_REQ,			vSmeProc_ManualHandoverJoin		},
	{SMEMSG_HANDOVER_JOIN_REQ,	vSmeProc_HandoverJoin			},
	{SMEMSG_DEAUTHEN_IND,		vSmeProc_DeauthenInd			},
	//{SMEMSG_DISASSOC_IND,		vSmeProc_DisassocInd			},
	{SMEMSG_DISASSOC_IND,		vSmeProc_DeauthenInd			},
	{SMEMSG_POWERSAVE_REQ,		vSmeProc_PowerSaveReq			},
	{SMEMSG_AUTHEN_REQ,			vSmeProc_IbssAuth				},
	{SMEMSG_END_ROAMING,		vSmeProc_Disconnect				},//Only for IBSS, because
									//ESS may try to handover, its state will not be CONNECT
	//{SMEMSG_IBSS_JOIN_UPDATE_BSSID, vSmeProc_IBSSJoinUpdateBSSID},
	//for WPA countermeasure
	{SMEMSG_COUNTERMEASURE_MICFAIL_TIMEOUT,	vSmeProc_CountermeaureCancel		},
	{SMEMSG_COUNTERMEASURE_BLOCK_TIMEOUT,	vSmeProc_CountermeasureBlockCancel	},
	{K_NULL_MSG,				vProc_Null						}
};


//========= SME State Transition Table ==============================
static const K_TRANS* psSMETransTable[] =
{
	asDisabled,
	asInit_Scan,
	asScan_Ready,
	asStart_IBSS,
	asJoin_Pending,
	asJoin_Cfm,
	asAuthenticate_Pending,
	asAuthenticated,
	asConnected,
};

//=========================================================================
//      Subroutine of SME Module 
//=========================================================================
void SME_Init(PWB32_ADAPTER Adapter)
{

	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: MiniportInit\n"));
	#endif

	//------------- H/W ------------
	//hal_set_accept_beacon(&Adapter->sHwData, FALSE);
	hal_set_accept_beacon(&Adapter->sHwData, TRUE);
	hal_stop_sync_bss(&Adapter->sHwData);

	//------------- S/W ------------
	SME_ResetPara(Adapter);
	//Initilize SME timer
	///NdisMInitializeTimer(&((psSME)->nTimer),
	///					  Adapter->WbNdis.MiniportAdapterHandle,
    ///                      (PVOID) vSmeTimerHandler,
    ///                      (PVOID) Adapter);
	OS_TIMER_INITIAL( &((psSME)->nTimer),
                          (PVOID) vSmeTimerHandler,
                          (PVOID) Adapter);
}

void SME_ResetPara(PWB32_ADAPTER Adapter)
{

	SMEstate=DISABLED;
	psSME->boDUTmode=FALSE;
	// Initial SME default parameters
	psSME->bDesiredBSSType = ANYBSS_NET;
	psSME->AuthenRetryTimerVal=1650;	// 1000ms = 3*AUTH_FAIL_TIMEOUT of MLME
	psSME->JoinFailTimerVal=500;		// 500ms
	psSME->boStartIBSS=FALSE;
	psSME->boJoinReq=FALSE;
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("psSME->JoinReq == FALSE\n"));
	#endif
	psSME->wBeaconPeriod = LOCAL_DEFAULT_BEACON_PERIOD;	// default Beacon period 100ms
	psSME->wATIM_Window = LOCAL_DEFAULT_ATIM_WINDOW;	// default ATIM window 0 ms

	OS_MEMORY_COPY( psSME->abDesiredBSSID, "\xff\xff\xff\xff\xff\xff", MAC_ADDR_LENGTH );

	//11G TODO: the setting of privacy, short preamble, short slot time etc..
	psSME->wCapabilityInfo =  LOCAL_DEFAULT_ERP_CAPABILITY;

	psSME->encrypt_status = ENCRYPT_DISABLE;
	psSME->_dot11PrivacyInvoked=FALSE;
	//psSME->_dot11ExcludeUnencrypted=TRUE;
	psSME->_dot11PrivacyOptionImplemented=FALSE;
	psSME->_dot11WEPDefaultKeyID = 0;
	psSME->bDesiredAuthMode = OPEN_AUTH;
	//psSME->bDesiredAuthMode = WPA_AUTH;

	psLOCAL->wConnectedSTAindex = 0;
	psLOCAL->boHandover = FALSE;  // Initial, not Handover
	psLOCAL->ListenInterval = LOCAL_DEFAULT_LISTEN_INTERVAL;
	psLOCAL->CurrentChan.band = BAND_TYPE_OFDM_24;

	//11G TODO:
	psLOCAL->boNonERPpresent = FALSE;
	psLOCAL->boProtectMechanism = FALSE;
	psLOCAL->boShortPreamble = FALSE;
	psLOCAL->boShortSlotTime = FALSE;
	psLOCAL->CWMin = 255;	//set according to 802.11 spec.

	//#ifdef _WPA_
	psSME->wpa_ok = 0;
	//#endif
	//TODO : WPA2
	#ifdef _WPA2_
	psSME->PmkidTableIndex=0;//added by ws 05/05/04
	#endif //end def _WPA2_

	if (psLOCAL->bMacOperationMode == MODE_802_11_A)
	{
		psLOCAL->CurrentTxRate = RATE_6M;
		psLOCAL->CurrentTxRateForMng = RATE_6M;
	}
	else
	{
		psLOCAL->CurrentTxRate = RATE_1M;
		psLOCAL->CurrentTxRateForMng = RATE_1M;
	}
    
	GetSupportChanRange(Adapter);
	GetIbssChan(Adapter);
	//WBDEBUG((" ------ The IBSS channel is: band= %d, no=%d\n", psSME->IbssChan.band, psSME->IbssChan.ChanNo));
    psLOCAL->boMsRadioOff = 0;


	psLOCAL->SignalLostTh = 69;
	psLOCAL->SignalRoamTh = 68;
}

void SME_Entry(PWB32_ADAPTER Adapter, K_MSG* psSmeMsg)
{
	if (psSmeMsg->wMsgType==KNLMSG_RESET)
	{
		// reset state to DISABLED and stop Timer
		SMEstate=DISABLED;
		vSmeTimerStop(Adapter);
		//Reset_MTO();
		return;
	}
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: iSME s=%x, m=%x\n", psSME->wState, psSmeMsg->wMsgType));
	#endif
	vKNL_StateMachine(Adapter, psSMETransTable, 
							psSME->wState, psSmeMsg);
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: oSME s=%x\n", psSME->wState));
	#endif
}

void SME_Halt(PWB32_ADAPTER Adapter)
{
	#ifdef _PE_STATE_DUMP_
	//WBDEBUG(("STATE: MiniportHalt\n"));
	#endif
	vSmeTimerStop(Adapter);
	#ifdef _PE_STATE_DUMP_
	//WBDEBUG(("STATE: sme timer stop OK.\n"));
	#endif
	while (psSME->boInTimerHandler == TRUE)
	{
		///NdisMSleep(10000);//10ms
		OS_SLEEP( 10000 );
	}
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: SME halt.\n"));
	#endif

}

void SME_Stop(PWB32_ADAPTER Adapter)
{
	vSmeTimerStop(Adapter);
}

//============================================================================
// vActiveHWMAC_join --
//
// Description:
//   Fill the H/W related settings when join with some BSS.
//
// Arguments:
//   Adapter    -   The handle of an adapter bock.
//
//============================================================================
void vActiveHWMAC_join(PWB32_ADAPTER Adapter)
{
	USHORT	wDscptIndex;
	K_MSG	sMsg;
	UCHAR		OpRate[MAX_OPT_RATE_SET], OpRateCount;
	ChanInfo ChanTmp;

	//12/03/03' : to avoid the join action is interrupted by scan
	sMsg.wMsgType = SCANMSG_STOP_SCAN;
	sMsg.pMsgPtr = NULL;
	Scan_Entry(Adapter, &sMsg);

	wDscptIndex = psSME->wDesiredJoinBSS;
	// Stop to synchronize with a BSS if it does.
	hal_stop_sync_bss(&Adapter->sHwData);

	ChanTmp.band = psBSS(wDscptIndex)->band;
	ChanTmp.ChanNo = psBSS(wDscptIndex)->DS_Parameter_Set.Current_Channel;
	hal_set_current_channel(&Adapter->sHwData, ChanTmp);
    // Write the SSID
	hal_set_ssid(&Adapter->sHwData, psBSS(wDscptIndex)->SSID.SSID,
					psBSS(wDscptIndex)->SSID.Length);
	//dump SSID
	#ifdef _PE_STATE_DUMP_
	{
		UCHAR ssid[50];

		OS_MEMORY_COPY( ssid, (UCHAR *)psBSS(wDscptIndex)->SSID.SSID, (UCHAR)psBSS(wDscptIndex)->SSID.Length);
		ssid[psBSS(wDscptIndex)->SSID.Length] = '\0';
		WBDEBUG(("join ssid=%s\n", ssid));
	}
	#endif
    // Write the capability information
	hal_set_cap_info(&Adapter->sHwData, psSME->wCapabilityInfo);
    // Write the BSSID
	hal_set_bssid(&Adapter->sHwData, psBSS(wDscptIndex)->abBssID);
    // Write the Beacon Interval
	hal_set_beacon_period(&Adapter->sHwData, psBSS(wDscptIndex)->Beacon_Period);

	hal_set_rsn_wpa(&Adapter->sHwData,&psLOCAL->RSN_IE_Bitmap,&psLOCAL->RSN_OUI_Type,psSME->bDesiredAuthMode); //added by WS 07/22/04

    // Write the supported rate
	//basic rates follow the target STA
	hal_set_basic_rates(&Adapter->sHwData,
						 psSME->BSSBasicRateSet,
						 psSME->NumOfBSSBasicRate);
	//operational rate use local supported
	//hal_set_op_rates(&Adapter->sHwData,
	//				 psSME->OperationalRateSet,
	//				 psSME->NumOfOperationalRate);
	//Operational rates will include the basic rates to avoid the condition that
	// supported rate element is lack of operational rates.
	OS_MEMORY_COPY( OpRate, psSME->BSSBasicRateSet, psSME->NumOfBSSBasicRate );
	OS_MEMORY_COPY( OpRate + psSME->NumOfBSSBasicRate, psSME->OperationalRateSet, psSME->NumOfOperationalRate );
	OpRateCount = psSME->NumOfBSSBasicRate + psSME->NumOfOperationalRate;
	hal_set_op_rates(&Adapter->sHwData, OpRate, OpRateCount);

	//Before the connection is successful, always use the long preamble
	psLOCAL->boShortPreamble = 0;

    // Instruct the HW-MAC to synchronize with the specified BSS
    if (psBSS(wDscptIndex)->bBssType == ESS_NET)
    {
        //NdisStallExecution(1);
        hal_join_request(&Adapter->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE);
    }
	else
	{
        //NdisStallExecution(1);
        hal_join_request(&Adapter->sHwData, WLAN_BSSTYPE_INDEPENDENT);
	}
	{
		//while (psBSS(wDscptIndex)->DS_Parameter_Set.Current_Channel != Adapter->sHwData.Channel)
		//	NdisStallExecution(100);
	}
	return;
}

//============================================================================
// vActiveHWMAC_IBSS --
//
// Description:
//   Fill the H/W related settings when start an IBSS.
//
// Arguments:
//   Adapter    -   The handle of an adapter bock.
//   psDesData	-	pointer of descriptor data that contains the parameters
//					to start an IBSS.
//============================================================================
void vActiveHWMAC_IBSS(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData)
{
	K_MSG	sMsg;
	UCHAR		OpRate[MAX_OPT_RATE_SET], OpRateCount;
	ChanInfo ChanTmp;

	//12/03/03' : to avoid the join action is interrupted by scan
	sMsg.wMsgType = SCANMSG_STOP_SCAN;
	sMsg.pMsgPtr = NULL;
	Scan_Entry(Adapter, &sMsg);

    // Stop to synchronize with a BSS if it does.
	hal_stop_sync_bss(&Adapter->sHwData);

    // Write the SSID
	hal_set_ssid(&Adapter->sHwData, psDesData->SSID.SSID, psDesData->SSID.Length);

    // Write the capability information
    // Do not report short preamble capability since once the STA starts an IBSS
    // ,the STA cannot connect (e.g. Ping) to the NIC (ATMEL chip) for the IP layer
    // although the NIC (ATMEL chip) can join succesfully this IBSS.
    // ATMEL does not reply to the STA with short preample capability.?
    //
    // CapabilityInfo |= 0x0020;       // Short preamble
	hal_set_cap_info(&Adapter->sHwData, psDesData->CapabilityInformation.wValue);

	ChanTmp.band = psDesData->band;
	ChanTmp.ChanNo = psDesData->DS_Parameter_Set.Current_Channel;
	hal_set_current_channel(&Adapter->sHwData, ChanTmp);

	hal_set_basic_rates(&Adapter->sHwData,
						psSME->BSSBasicRateSet,
						psSME->NumOfBSSBasicRate);
//	hal_set_op_rates(&Adapter->sHwData,
//					 psSME->OperationalRateSet,
//					 psSME->NumOfOperationalRate);
	//Operational rates will include the basic rates to avoid the condition that
	// supported rate element is lack of operational rates.
	OS_MEMORY_COPY( OpRate, psSME->BSSBasicRateSet, psSME->NumOfBSSBasicRate );
	OS_MEMORY_COPY( OpRate + psSME->NumOfBSSBasicRate, psSME->OperationalRateSet, psSME->NumOfOperationalRate );
	OpRateCount = psSME->NumOfBSSBasicRate + psSME->NumOfOperationalRate;
	hal_set_op_rates(&Adapter->sHwData, OpRate, OpRateCount);
	hal_set_bssid(&Adapter->sHwData, psDesData->abBssID);

	hal_set_rsn_wpa(&Adapter->sHwData,&psLOCAL->RSN_IE_Bitmap,&psLOCAL->RSN_OUI_Type,psSME->bDesiredAuthMode); //added by WS 07/22/04

	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: IBSS write BSSID =%02x-%02x-%02x-%02x-%02x-%02x\n",
								psDesData->abBssID[0],psDesData->abBssID[1],
								psDesData->abBssID[2],psDesData->abBssID[3],
								psDesData->abBssID[4],psDesData->abBssID[5]));
	#endif
    // Write the Beacon Interval and probe delay
	hal_set_beacon_period(&Adapter->sHwData, psDesData->Beacon_Period);

    // Write the ATIM Window
	hal_set_atim_window(&Adapter->sHwData, psDesData->wATIM_Window);
	#ifdef _TMP_MARK_
    if (psSME->wATIM_Window == 0)
        CardDisableATIMMode(Adapter);
    else
        CardEnableATIMMode(Adapter);
    //NdisStallExecution(1);
	#endif

    // Instruct the HW-MAC to initialize an IBSS
	hal_start_bss(&Adapter->sHwData, WLAN_BSSTYPE_INDEPENDENT);
    //NdisStallExecution(2);
    
    //wiat for another STA to join this IBSS
	//hal_set_accept_beacon(&Adapter->sHwData, TRUE);
}

//============================================================================
// vNetConnectIndicate --
//
// Description:
//   Indicate the connection status to NDIS
//
// Arguments:
//   Adapter    -   The handle of an adapter bock.
//
//============================================================================
void vNetConnectIndicate(PWB32_ADAPTER Adapter)
{
	#ifdef _PE_STATE_DUMP_
	UCHAR ssid[33];

	OS_MEMORY_COPY( ssid, psBSS(psLOCAL->wConnectedSTAindex)->SSID.SSID,
					psBSS(psLOCAL->wConnectedSTAindex)->SSID.Length );
	ssid[psBSS(psLOCAL->wConnectedSTAindex)->SSID.Length] = '\0';
	WBDEBUG(("STATE: Connect! ,Idx=%x ,", psLOCAL->wConnectedSTAindex));
	WBDEBUG(("SSID=%s\n",ssid));
	#endif
    Adapter->sLocalPara.bWepKeyError= FALSE;//added by ws 02/02/04
	Adapter->sLocalPara.bToSelfPacketReceived = FALSE;
    Adapter->sLocalPara.WepKeyDetectTimerCount= 2 * 100; /// 2 seconds
    
    //for receiving packets from AP and address3 is ourself 
    //the register of accepting all packets should be open until pass 2*1000.  
    if(psSME->encrypt_status==ENCRYPT_WEP)
       hal_set_accept_promiscuous(&Adapter->sHwData,1);
    
	hal_set_connect_info(&Adapter->sHwData, TRUE);
	OS_CONNECT_STATUS_INDICATE( Adapter, OS_CONNECTED );
	FillEventLog(Adapter, EVENT_CONNECT);
}

//============================================================================
// vNetDisconnectInd --
//
// Description:
//   Indicate the disconnection status to NDIS
//
// Arguments:
//   Adapter    -   The handle of an adapter bock.
//
//============================================================================
void vNetDisconnectInd(PWB32_ADAPTER Adapter)
{
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: DisConnect\n"));
	#endif
	hal_set_connect_info(&Adapter->sHwData, FALSE);
	OS_CONNECT_STATUS_INDICATE( Adapter, OS_DISCONNECTED );
	FillEventLog(Adapter, EVENT_DISCONNECT);
}

//============================================================================
// boJoinfilter --
//
// Description:
//   Determine join with target STA or not.
//   	-Check if all the basic rates of the target STA are supported by 
//			our H/W. If it is, accept it. 
//
//
// Arguments:
//   Adapter    -   The handle of an adapter bock.
//   wBssIdx    -   BSSDescriptor entry index of desired joining STA
//
// Return:
//   0      - give up this join
//   1      - accept this join
//============================================================================
BOOL boJoinfilter(PWB32_ADAPTER Adapter, USHORT wBssIdx)
{
	ULONG tmp,SupportRateBitmap;
	UCHAR i;
//	UCHAR	ChanLimit;

	//filter 2.4G channel based on the region
	if (psBSS(wBssIdx)->band == BAND_TYPE_OFDM_24)
	{
/*
		switch (psLOCAL->region)
		{
			case REGION_EUROPE:
				ChanLimit = 13;
				break;
			case REGION_JAPAN:
			case REGION_UNKNOWN:
				ChanLimit = 14;
				break;
			case REGION_USA:
			default:
				ChanLimit = 11;
				break;
		}
*/
		//if (psBSS(wBssIdx)->DS_Parameter_Set.Current_Channel > ChanLimit)
		if (boChanFilter(Adapter, psBSS(wBssIdx)->DS_Parameter_Set.Current_Channel))
		{
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("Join filter ==> region\n"));
			#endif
			return 0;
		}
	}

	if (psLOCAL->bMacOperationMode == MODE_802_11_A)
		SupportRateBitmap = LOCAL_OFDM_SUPPORTED_RATES_BITMAP;
	else if (psLOCAL->bMacOperationMode == MODE_802_11_B)
		SupportRateBitmap = LOCAL_11B_SUPPORTED_RATE_BITMAP;
	else
		SupportRateBitmap = LOCAL_ALL_SUPPORTED_RATES_BITMAP;

	//check basic rates
	tmp =	psBSS(wBssIdx)->dwBasicRateBitmap ^ SupportRateBitmap;
	if (tmp!=0)
	{
		if ((tmp & psBSS(wBssIdx)->dwBasicRateBitmap)!=0)
		{
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("Join filter ==> basic rate\n"));
			#endif
			//Some basic rates of target STA are not supported by our H/W
			FillEventLog(Adapter, EVENT_JOIN_FILTER|EVENT_REASON_FILTER_BASIC_RATE);
			return 0;
		}
	}
	//check capability
	if (psSME->_dot11PrivacyInvoked != psBSS(wBssIdx)->CapabilityInformation.Capability.CF_Privacy)
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("Join filter ==> capability\n"));
		#endif
		FillEventLog(Adapter, EVENT_JOIN_FILTER|EVENT_REASON_FILTER_PRIVACY);
		return 0;
	}

	Assemble_IE(Adapter, wBssIdx);
	if (psBSS(wBssIdx)->RsnIe_len == 0)	//RSN element doesn't exist
	{
		if (psSME->bDesiredAuthMode > ANY_AUTH)
		{
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("Join filter ==> Auth mode\n"));
			#endif
			FillEventLog(Adapter, EVENT_JOIN_FILTER|EVENT_REASON_FILTER_AUTH_MODE);
			return 0;
		}
	}

	//added by ws 04/22/05
	if((psSME->bDesiredAuthMode==WPA_AUTH)||(psSME->bDesiredAuthMode==WPAPSK_AUTH))
	{
		for(i=0;i<psBSS(wBssIdx)->pairwise_key_cipher_suite_count;i++)
		{
			if((psSME->DesiredEncrypt == psBSS(wBssIdx)->pairwise_key_cipher_suites[i].SuitSelector.Type))
				return 1;
		}

		return 0;
	}
	#ifdef _WPA2_
	else if((psSME->bDesiredAuthMode==WPA2_AUTH)||(psSME->bDesiredAuthMode==WPA2PSK_AUTH))
	{
		for(i=0;i<psBSS(wBssIdx)->wpa2_pairwise_key_cipher_suite_count;i++)
		{
			if((psSME->DesiredEncrypt <= psBSS(wBssIdx)->wpa2_pairwise_key_cipher_suites[i].SuitSelector.Type))
				return 1;
		}

		return 0;
	}
	#endif
	return 1;
}

//============================================================================
// SetDesiredLocalRate --
//
// Description:
//	 The operational rates of local STA will be the ones that local H/W supports
//	except those that desired joining STA doesn't support.
//
// Arguments:
//   Adapter    -   The handle of an adapter bock.
//   wBssIdx    -   BSSDescriptor entry index of desired joining STA
//
// Return:	None
//
//============================================================================
void SetDesiredLocalRate(PWB32_ADAPTER Adapter, USHORT wIndex)
{
	ULONG	tmp1, tmp2, tmp3;
	UCHAR 	BitIndex,i=0;
	ULONG	BitMap;
	UCHAR	num1;

	if (psBSS(wIndex)->bBssType == ESS_NET)
	{
		//basic rates follow the destination BSS
		//Suppose AP won't use OFDM rates at channel 14
		psSME->NumOfBSSBasicRate = (UCHAR)strlen(psBSS(wIndex)->BasicRate);
		OS_MEMORY_COPY( psSME->BSSBasicRateSet, psBSS(wIndex)->BasicRate, psSME->NumOfBSSBasicRate );
		psSME->BasicRateBitmap = psBSS(wIndex)->dwBasicRateBitmap;
	}
	else
	{
		//The STAs in the IBSS may have different mode settings, so we can't just follow someone's setting
		if (psLOCAL->bMacOperationMode == MODE_802_11_A)
			psSME->BasicRateBitmap = LOCAL_11A_BASIC_RATE_BITMAP;
		else if (psLOCAL->bMacOperationMode == MODE_802_11_BG_IBSS)
		{
			if (psBSS(wIndex)->DS_Parameter_Set.Current_Channel != 14)
				psSME->BasicRateBitmap = LOCAL_11G_BASIC_RATE_BITMAP;
			else	//channel 14 can't use OFDM rates
				psSME->BasicRateBitmap = LOCAL_11B_BASIC_RATE_BITMAP;
		}
		else if (psLOCAL->bMacOperationMode == MODE_AUTO)
		{
			if (psBSS(wIndex)->band == BAND_TYPE_OFDM_5)
				psSME->BasicRateBitmap = LOCAL_11A_BASIC_RATE_BITMAP;
			else
				psSME->BasicRateBitmap = LOCAL_11B_BASIC_RATE_BITMAP;
		}
		else
			psSME->BasicRateBitmap = LOCAL_11B_BASIC_RATE_BITMAP;

		num1 = 0;
		for (BitIndex=0 ; BitIndex<32; BitIndex++)
		{
			tmp3	= 1<<BitIndex;
			if (psSME->BasicRateBitmap & tmp3)
				psSME->BSSBasicRateSet[num1++] = bBitmapToRate(BitIndex);
		}
		psSME->NumOfBSSBasicRate = num1;
	}

	//management frames use lowest basic rate to transmit
	BitMap = psSME->BasicRateBitmap;
	for (BitIndex=0 ; BitIndex<32; BitIndex++)
	{
		if( BitMap & (1<<BitIndex) )
			break;
	}
	psLOCAL->CurrentTxRateForMng = bBitmapToRate(BitIndex);

	if (psBSS(wIndex)->bBssType==ESS_NET)
	{
		if (psLOCAL->bMacOperationMode == MODE_802_11_A)
			tmp1 = LOCAL_OFDM_SUPPORTED_RATES_BITMAP;
		else if (psLOCAL->bMacOperationMode == MODE_802_11_B)
			tmp1 = LOCAL_11B_SUPPORTED_RATE_BITMAP;
		else
			tmp1 = LOCAL_ALL_SUPPORTED_RATES_BITMAP;

		if (psBSS(wIndex)->DS_Parameter_Set.Current_Channel == 14)
			tmp1 = LOCAL_11B_SUPPORTED_RATE_BITMAP;

		//It will follow the operation rate settings of peer BSS except the rates
		//we don't suport.
		//It imply that it excludes the rates that peer BSS doesn't support.
		tmp2 = psBSS(wIndex)->dwOperationalRateBitmap ^ tmp1;
		tmp1 &= (~tmp2);

		psSME->OpRateBitmap = tmp1;
		for (BitIndex=0 ; BitIndex<32; BitIndex++)
		{
			tmp2	= 1<<BitIndex;
			if (tmp1&tmp2)
				psSME->OperationalRateSet[i++] = bBitmapToRate(BitIndex);
		}
		psSME->NumOfOperationalRate = i;
	}
	else
	{
		if (psLOCAL->bMacOperationMode == MODE_802_11_A)
			tmp1 = LOCAL_11A_OPERATION_RATE_BITMAP;
		else if (psLOCAL->bMacOperationMode == MODE_802_11_BG_IBSS)
		{
			if (psBSS(wIndex)->DS_Parameter_Set.Current_Channel != 14)
				tmp1 = LOCAL_11G_OPERATION_RATE_BITMAP;
			else
				tmp1 = 0;
		}
		else if (psLOCAL->bMacOperationMode == MODE_AUTO)
		{
			if (psBSS(wIndex)->band == BAND_TYPE_OFDM_5)
				tmp1 = LOCAL_11A_OPERATION_RATE_BITMAP;
			else
				tmp1 = 0;
		}
		else
			tmp1 = 0;
		psSME->OpRateBitmap = tmp1;
		if (tmp1 != 0)
		{
			for (BitIndex=0 ; BitIndex<32; BitIndex++)
			{
				tmp2	= 1<<BitIndex;
				if (tmp1&tmp2)
					psSME->OperationalRateSet[i++] = bBitmapToRate(BitIndex);
			}
			psSME->NumOfOperationalRate = i;
		}
		else
			psSME->NumOfOperationalRate = 0;
	}
}
//============================================================================
// boJoinExistBSS --
//
// Description:
//   One BSSDescriptor entry of the desired SSID or BSSID has been found.
//   According to the desired joining BSS type and the BSS type of the found STA,
//   decide to join the ESS/IBSS, start IBSS, or do nothing.
//
// Arguments:
//   Adapter    -   The handle of an adapter bock.
//   wBssIdx    -   BSSDescriptor entry index of the found STA
//
// Return:
//   0      - FAIL
//   1      - SUCCESS
//============================================================================
BOOL boJoinExistBSS(PWB32_ADAPTER Adapter, USHORT wFoundIndex)
{
	//Convert the rate related information into bitmap value
	vRateToBitmap(Adapter, wFoundIndex);
	if (psSME->bDesiredBSSType == ANYBSS_NET || psSME->bDesiredBSSType == ESS_NET)
	{
		if (psBSS(wFoundIndex)->bBssType==ESS_NET)
		{
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("STATE: ESS FOUND, JOIN ESS\n"));
			#endif
			psBSS(wFoundIndex)->boERP = boIsERPsta(Adapter, wFoundIndex);
			//11G TODO: Check basic rates, supported rates or other parameters to decide
			//			continue or not
			//beacons of Buffalo 11G AP doesn't has extended supported rate element,
			// all rates setting are been included in supported rate element.
			/**/
			if (!boJoinfilter(Adapter, wFoundIndex))
			{
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("!!! Join filter\n"));
				#endif
				return 0;
			}
			SetDesiredLocalRate(Adapter, wFoundIndex);
			//not support PBCC
			psSME->wCapabilityInfo =
					psBSS(wFoundIndex)->CapabilityInformation.wValue & (~CAPABILITY_PBCC_BIT);
			/**/
			ClearOldData(Adapter);
			psSME->wDesiredJoinBSS = wFoundIndex;
			SMEstate=JOIN_PENDING;
			vSmeTimerStart(Adapter,psSME->JoinFailTimerVal);
			//TODO : [WKCHEN] How about the probe response??
			//AddIBSSIe(Adapter,psBSS(wFoundIndex));//added by WS 07/22/04
			vActiveHWMAC_join(Adapter);
			return 1;
		}
	}
	if (psSME->bDesiredBSSType == ANYBSS_NET || psSME->bDesiredBSSType == IBSS_NET)
	{
		USHORT wNewIndex;

		//Note: In CONNECTED state, if Disconnected-IND/Deauthen_REQ are received,
		// it must clear local description.

		if (psBSS(wFoundIndex)->bBssType==IBSS_NET)
		{
			//if ((wNewIndex=wBSSallocateEntry(Adapter))==0)	//for local used
			//	return 0;
			if ((wNewIndex=wBSSsearchMACaddr(Adapter, psLOCAL->ThisMacAddress, psSME->IbssChan.band)) == 0)
			{
				if ((wNewIndex=wBSSGetEntry(Adapter)) == 0)
						return 0;	// Dropt
			}
			psBSS(wFoundIndex)->boERP = boIsERPsta(Adapter, wFoundIndex);
			if (!boJoinfilter(Adapter, wFoundIndex))
			{
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("!! Join filter\n"));
				#endif
				return 0;
			}
			SetDesiredLocalRate(Adapter, wFoundIndex);
			psSME->wCapabilityInfo = psBSS(wFoundIndex)->CapabilityInformation.wValue;
			ClearOldData(Adapter);
			//ClearOldData may clear the state of the desired join device
			MLME_findSTA(psBSS(wFoundIndex));
			//TODO: 1009
			//psLOCAL->wConnectedSTAindex = wNewIndex;
			psSME->wDesiredJoinBSS = wNewIndex;
			//copy the found BSS data to local description
			OS_MEMORY_COPY( psBSS(wNewIndex), psBSS(wFoundIndex), sizeof(WB_BSSDESCRIPTION) );
			//The state of psBSS(wNewIndex) is IDLE_SCAN, copy from psBSS(wDscptIndex)
			// update LocalMACaddr,...etc
			//11G TODO: some parameters also need to be modified, such as supported
			//			rates, capability, ..
			OS_MEMORY_COPY( psBSS(wNewIndex)->abPeerAddress, psLOCAL->ThisMacAddress, MAC_ADDR_LENGTH );
			//TODO: 1009
			//vActiveHWMAC_IBSS(Adapter, psBSS(wFoundIndex));
			SMEstate = JOIN_PENDING;
			AddIBSSIe(Adapter,psBSS(wFoundIndex));
			vActiveHWMAC_join(Adapter);
			psLOCAL->JoinerInIbss[0] = (UCHAR)wFoundIndex;
			psLOCAL->NoOfJoinerInIbss = 1;
			psLOCAL->HwBssidValid = FALSE;
			vSmeTimerStart(Adapter,psSME->JoinFailTimerVal);
			//MLME_JoinCfm(psBSS(wNewIndex),   // because psBSS(wNewIndex) is IDLE_SCAN, don't call JoinCfm() again.
			//					psBSS(wNewIndex)->bBssType);
			//TODO: 1009
			//SMEstate=START_IBSS;
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("STATE: IBSS FOUND, JOIN IBSS\n"));
			#endif
			return 1;
		}
		else	//desire type == IBSS_NET, found type == ESS_NET
		{
			ClearOldData(Adapter);
			vSmeProc_StartIBSSActive(Adapter, NULL);
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("STATE: ESS FOUND, START IBSS\n"));
			#endif
			return 1;
		}
	}
	psSME->wDesiredJoinBSS = 0;
	return 0;	//desire type == ESS_NET, found type == IBSS_NET => end this request
}

//============================================================================
// boJoinNonExistBSS --
//
// Description:
//   The BSSDescriptor entry of the desired SSID or BSSID does not been found.
//   According to the desired joining BSS type, start IBSS or do nothing.
//
// Arguments:
//   Adapter    -   The handle of an adapter bock.
//
// Return:
//   0      - FAIL
//   1      - SUCCESS
//============================================================================
BOOL boJoinNonExistBSS(PWB32_ADAPTER Adapter)
{
	if (psSME->bDesiredBSSType == ANYBSS_NET || psSME->bDesiredBSSType == IBSS_NET)
	{
		ClearOldData(Adapter);
		vSmeProc_StartIBSSActive(Adapter, NULL);
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: STA NOT FOUND, START IBSS\n"));
		#endif
		return 1;
	}
	else
	{
		ClearOldData(Adapter);//TODO: 20030319 added, not test by WHQL
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: STA NOT FOUND, Desired bss type = ESS_NET.\n"));
		#endif
		psSME->wDesiredJoinBSS = 0;
		return 0;
	}
}

void ClearOldData(PWB32_ADAPTER Adapter)
{
	if (psLOCAL->wConnectedSTAindex != 0)
	{
		Roam_ResetPara(Adapter); //reset(stop) roaming task no matter if it is active
		vNetDisconnectInd(Adapter);

		if (psBSS(psLOCAL->wConnectedSTAindex)->bBssType == ESS_NET)
		{
			psLOCAL->wOldSTAindex = psLOCAL->wConnectedSTAindex; // wOldSTAindex only for <REASSOC> msg-frame
			MLME_findSTA(psBSS(psLOCAL->wConnectedSTAindex));//update its state to IDLE_SCAN
		}
		else
		{
			psLOCAL->NoOfJoinerInIbss = 0;
			//MLME_IBSSinitState(Adapter);
			MLME_initState(psBSS(psLOCAL->wConnectedSTAindex));
			hal_ibss_disconnect(&Adapter->sHwData);
		}
		psLOCAL->wConnectedSTAindex = 0;
	}
	else
	{
		if (SMEstate == START_IBSS)
		{
			psLOCAL->NoOfJoinerInIbss = 0;
			MLME_initState(psBSS(psSME->wDesiredJoinBSS));
			hal_ibss_disconnect(&Adapter->sHwData);
		}
	}
//	#ifdef _WPA_
//	if ((psSME->bDesiredAuthMode == WPA_AUTH) ||
//		(psSME->bDesiredAuthMode == WPAPSK_AUTH) ||
//		(psSME->bDesiredAuthMode == WPANONE_AUTH))
//	{
//		sme_clear_all_mapping_key(Adapter);
//		sme_clear_all_default_key(Adapter);
//		psSME->pairwise_key_ok = 0;
//		psSME->group_key_ok = 0;
//		psSME->wpa_ok = 0;
//	}
//	#endif

}

//============================================================================
// boJoinAction --
//
// Description:
//		Based on the requirement(SSID, BSSID, or none) of JOIN_REQ, perform different
//	actions.
// Arguments:
//		Adapter    -   The handle of an adapter bock.
//
// Return:
//		0      - FAIL
//		1      - SUCCESS
//============================================================================
BOOL boJoinAction(PWB32_ADAPTER Adapter)
{
	BOOL 	ret = 0;
	USHORT	wIndex,i;

	if (psSME->sDesiredSSID.Length!=0)
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: Desired SSID Join\n"));
		#endif
		if( !OS_MEMORY_COMPARE( psSME->abDesiredBSSID, "\xff\xff\xff\xff\xff\xff", MAC_ADDR_LENGTH ) )
		{
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("STATE: Dedicated BSSID Join\n"));
			#endif
			wIndex=wBSSfindDedicateCandidate(Adapter, &psSME->sDesiredSSID, psSME->abDesiredBSSID);
		}
		else
		{
			wIndex=wBSSfindSSID(Adapter, &psSME->sDesiredSSID);
		}
		if (wIndex != 0)	//decription exist
			ret = boJoinExistBSS(Adapter, wIndex);
		else
			ret = boJoinNonExistBSS(Adapter);
	}
	else if( !OS_MEMORY_COMPARE( psSME->abDesiredBSSID, "\xff\xff\xff\xff\xff\xff", MAC_ADDR_LENGTH ) )
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: Desired BSSID Join\n"));
		#endif
		if ((wIndex=wBSSfindBssID(Adapter, psSME->abDesiredBSSID)) != 0)	//decription exist
		{
			ret = boJoinExistBSS(Adapter, wIndex);
		}
		else
		{
			//ret = boJoinNonExistBSS(Adapter);
			ret = 0;
		}
	}
	else	//join with anyone
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: Join with anyone\n"));
		#endif
		for (i=2; i<MAX_BSS_DESCRIPT_ELEMENT; i++)
		{
			//TODO: decide the best candidate
			if ((boMLME_FoundSTAinfo(psBSS(i))) &&
				(psBSS(i)->bBssType == ESS_NET) &&
				(psBSS(i)->CapabilityInformation.Capability.CF_Privacy == psSME->_dot11PrivacyInvoked))
			{
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("STATE: ESS FOUND, JOIN ESS\n"));
				#endif
				vRateToBitmap(Adapter, i);
				psBSS(i)->boERP = boIsERPsta(Adapter, i);
				//Check basic rates, supported rates or other parameters to decide continue or not
				if (!boJoinfilter(Adapter, i))
				{
					#ifdef _PE_STATE_DUMP_
					WBDEBUG(("! Join filter\n"));
					#endif
					continue;
				}

				#ifdef _PE_STATE_DUMP_
				{//For debug
					UCHAR ssid[33];

					OS_MEMORY_COPY( ssid, psBSS(i)->SSID.SSID, psBSS(i)->SSID.Length );
					ssid[psBSS(i)->SSID.Length] = '\0';
					WBDEBUG(("Join with randon AP, SSID=%s\n",ssid));
				}
				#endif
				SetDesiredLocalRate(Adapter, i);
				//not support PBCC
				psSME->wCapabilityInfo =
						psBSS(i)->CapabilityInformation.wValue & (~CAPABILITY_PBCC_BIT);

				ClearOldData(Adapter);
				psSME->wDesiredJoinBSS = i;
				SMEstate=JOIN_PENDING;
				vActiveHWMAC_join(Adapter);
				vSmeTimerStart(Adapter,psSME->JoinFailTimerVal);
				ret = 1;
				break;
			}
		}
	}
	return (ret);

}

void vSmeTimerStart(PWB32_ADAPTER Adapter, UINT timeout_value)
{
	if (Adapter->sLocalPara.ShutDowned == FALSE)
	{// timer unit is 'ms'
	    if (timeout_value<MIN_TIMEOUT_VAL) timeout_value=MIN_TIMEOUT_VAL;
			OS_TIMER_SET( &(psSME->nTimer), timeout_value );
	}
}

void vSmeTimerStop(PWB32_ADAPTER Adapter)
{

	OS_TIMER_CANCEL( &psSME->nTimer, &boValue );
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: sme cancel timer return valule =%x\n", boValue));
	#endif
}

//for only one argument
void vSmeTimerHandler_1a(IN PVOID	Data)
{
	vSmeTimerHandler(NULL, (PWB32_ADAPTER)Data, NULL, NULL);
}

void vSmeTimerHandler(IN PVOID			SystemSpecific1,
					  IN PWB32_ADAPTER 	Adapter,
					  IN PVOID			SystemSpecific2,
					  IN PVOID			SystemSpecific3)
{
	K_MSG sTimerMsg;

	psSME->boInTimerHandler = TRUE;
 	sTimerMsg.wMsgType = SMEMSG_TIMEOUT;
	sTimerMsg.pMsgPtr = NULL;
	SME_Entry(Adapter, &sTimerMsg);
	psSME->boInTimerHandler = FALSE;
}

//======================================================================================
//      Action Functions of SME State Transition Table 
//======================================================================================
void vSmeProc_ScanReq(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	K_MSG sMsg;

	SMEstate=INIT_SCAN;
	sMsg.wMsgType = SCANMSG_SCAN_REQ;
	sMsg.wInstance = 0;
	sMsg.pMsgPtr = psMsg->pMsgPtr;	//scan request parameters
	Scan_Entry(Adapter,&sMsg);
}

void vSmeProc_ScanCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	K_MSG sScanMsg;

	SMEstate = SCAN_READY;
	if (psSME->boStartIBSS == TRUE)
	{
		psSME->boStartIBSS = FALSE;
		vSmeProc_StartIBSSActive(Adapter, NULL);
	}
	else if (psSME->boJoinReq == TRUE)
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("Scan confirm, join request\n"));
		#endif
		if (boJoinAction(Adapter) == 0)
		{
			//psSME->bJoinScanCount is the number of "scan" and "then try to join".
			if (psSME->bJoinScanCount != 0)
			{
				SCAN_REQ_PARA	sScanReqPara;

				#ifdef _PE_STATE_DUMP_
				//WBDEBUG(("Scan confirm, join request, psSCAN->boSave = FALSE\n"));
				#endif
				//psSCAN->boSave = FALSE;
				sScanMsg.wMsgType = SCANMSG_SCAN_REQ;
				sScanMsg.wInstance = 0;
				//sScanMsg.pMsgPtr = NULL;
				//Scan with unicast SSID. Only change SSID parameters.
				OS_MEMORY_COPY( &sScanReqPara, psSCANREQ , sizeof(SCAN_REQ_PARA) );
				OS_MEMORY_COPY( &sScanReqPara.sSSID, &psSME->sDesiredSSID, sizeof(struct SSID_Element) );
				sScanMsg.pMsgPtr = &sScanReqPara;
				Scan_Entry(Adapter,&sScanMsg);
				psSME->bJoinScanCount--;
			}
			else
			{
				psSME->boJoinReq = FALSE;
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("psSME->JoinReq == FALSE\n"));
				#endif
			}
		}
		else
		{
			psSME->boJoinReq = FALSE;
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("psSME->JoinReq == FALSE\n"));
			#endif
			psSME->bJoinScanCount = 0;
		}
	}
}

void vSmeProc_JoinReq(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	// put Join-Req in Queue, start Join activity after Scan-Confirm
	psSME->boJoinReq=TRUE;
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("psSME->JoinReq == TRUE\n"));
	#endif
}

void vSmeProc_JoinActive(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	K_MSG sScanMsg;

	if (boJoinAction(Adapter) == 0)
	{
		SCAN_REQ_PARA	sScanReqPara;

		//psSCAN->boSave = FALSE;
		sScanMsg.wMsgType = SCANMSG_SCAN_REQ;
		sScanMsg.wInstance = 0;
		//sScanMsg.pMsgPtr = NULL;
		OS_MEMORY_COPY( &sScanReqPara, psSCANREQ , sizeof(SCAN_REQ_PARA) );
		OS_MEMORY_COPY( &sScanReqPara.sSSID, &psSME->sDesiredSSID, sizeof(struct SSID_Element) );
		sScanMsg.pMsgPtr = &sScanReqPara;
		Scan_Entry(Adapter,&sScanMsg);
		psSME->boJoinReq = TRUE;
		#ifdef _PE_STATE_DUMP_
		//WBDEBUG(("psSME->JoinReq = TRUE, psSCAN->boSave = FALSE\n"));
		#endif
		//psSME->bJoinScanCount = 1;
		psSME->bJoinScanCount = 0;//no more retry(scan and join)
	}
	else
	{
		psSME->boJoinReq = FALSE;
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("psSME->JoinReq == FALSE\n"));
		#endif
		psSME->bJoinScanCount = 0;
	}
}



void vSmeProc_StartIBSSReq(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	//This request is being pended.
	//put START IBSS request in Queue, start START IBSS activity after Scan-Confirm
	psSME->boStartIBSS = TRUE;
}

void vSmeProc_StartIBSSActive(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	USHORT wBssIdx;

	//If there is another IBSS with the same SSID in the environment when we request to 
	//start an IBSS(has already set the H/W completely), the H/W will abandon 
	//to start and join with this IBSS.

	// User defined parameters are checked OK in GUI or Dispatch module.

	if ((wBssIdx=wBSSsearchMACaddr(Adapter, psLOCAL->ThisMacAddress, psSME->IbssChan.band)) == 0)
	{
		if ((wBssIdx=wBSSGetEntry(Adapter)) == 0)//For local used.
		{
			SMEstate = SCAN_READY;
				return;	// Dropt
		}
	}
	//else
	//{
		if (wBSScreateIBSSdata(Adapter, &Adapter->asBSSDescriptElement[wBssIdx]))
		{
			vRateToBitmap(Adapter, wBssIdx);
			//psLOCAL->wConnectedSTAindex = wBssIdx;
			psSME->wDesiredJoinBSS = wBssIdx;
			// fill HWMAC registers
			vActiveHWMAC_IBSS(Adapter, psBSS(wBssIdx));
			psLOCAL->HwBssidValid = FALSE;
			psLOCAL->boShortSlotTime = FALSE;
			hal_set_slot_time(&Adapter->sHwData, WLAN_SLOT_TIME_TYPE_LONG);
			SMEstate=START_IBSS;
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("START IBSS, local index =%x\n", wBssIdx));
			#endif
		}
		else
		{
			SMEstate = SCAN_READY;
			return;
		}
	//}
}

void vSmeProc_IbssStartCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	//UCHAR	BSSID[MAC_ADDR_LENGTH];
	USHORT	wDscptIndex, wPeerDscptIndex;
	K_MSG	sRoamMsg;
	//pK_MSG psMsg;
	//MLME_AUTHREQ_PARA	sAuthReqPara;

	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: IBSS start confirm\n"));
	#endif
	// Read the BSSID
	wDscptIndex = psSME->wDesiredJoinBSS;
	MLME_JoinCfm(psBSS(wDscptIndex), psBSS(wDscptIndex)->bBssType);
	psBSS(wDscptIndex)->boERP = boIsERPsta(Adapter, wDscptIndex);
/*
	SMEstate=JOIN_CFM;
	memcpy(sAuthReqPara.peerMACaddr, pGUIReq->PeerSTAAddr, MAC_ADDR_LENGTH);
	sAuthReqPara.wAuthAlgorithm = (USHORT)pGUIReq->AuthenType;
	psMsg->wMsgType = SMEMSG_AUTHEN_REQ;
	psMsg->pMsgPtr = &sAuthReqPara;  //used by IBSS AuthenReq: WKCHEN_NOTE1
	vSmeProc_IbssAuth(Adapter, psMsg);
	vSmeTimerStart(Adapter,psSME->JoinFailTimerVal);
*/
	wPeerDscptIndex = psMsg->wInstance;
	if( boCmpMacAddr( psBSS(wDscptIndex)->abBssID, psLOCAL->HwBssid ) == 0 ) //not equal
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("** BSSID of S/W and H/W are different. **\n"));
		WBDEBUG(("S/W BSSID=%x-%x-%x-%x-%x-%x\n",
					psBSS(wDscptIndex)->abBssID[0],psBSS(wDscptIndex)->abBssID[1],psBSS(wDscptIndex)->abBssID[2],
					psBSS(wDscptIndex)->abBssID[3],psBSS(wDscptIndex)->abBssID[4],psBSS(wDscptIndex)->abBssID[5]));
		#endif
		OS_MEMORY_COPY( psBSS(wDscptIndex)->abBssID, psLOCAL->HwBssid, MAC_ADDR_LENGTH );
		psBSS(wDscptIndex)->Beacon_Period = psBSS(wPeerDscptIndex)->Beacon_Period;
		psBSS(wDscptIndex)->CapabilityInformation.wValue =
				psBSS(wPeerDscptIndex)->CapabilityInformation.wValue;
	}
	psLOCAL->HwBssidValid = FALSE;

//#ifdef _WAIT_REMOVE_
	//12/27/03' added
	psLOCAL->wConnectedSTAindex = wDscptIndex;
	psLOCAL->JoinerInIbss[0] = (UCHAR)wDscptIndex;
	psLOCAL->JoinerInIbss[1] = (UCHAR)wPeerDscptIndex;
	psLOCAL->NoOfJoinerInIbss = 2;
	if (SMEstate != CONNECTED)
	{
		vNetConnectIndicate(Adapter);
		
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: IBSS connect confirm\n"));
		#endif
	}
	SMEstate=CONNECTED;

	if (psLOCAL->CWMin == 255)	// set according to 802.11 spec.
	{
	if (psBSS(psLOCAL->wConnectedSTAindex)->boERP)
		hal_set_cwmin(&Adapter->sHwData, 15);
	else
		hal_set_cwmin(&Adapter->sHwData, 31);
	}
	else
		hal_set_cwmin(&Adapter->sHwData, psLOCAL->CWMin);

	//Set H/W according to the new 11G settings
	//psLOCAL->boNonERPpresent = psBSS(psLOCAL->wConnectedSTAindex)->
	//										ERP_Information_Set.NonERP_Present;
	//psLOCAL->boProtectMechanism = psBSS(psLOCAL->wConnectedSTAindex)->
	//										ERP_Information_Set.Use_Protection;
	//TODO: protection mode setting
	//hal_set_protection_mode()
	if (psLOCAL->bPreambleMode == AUTO_MODE)
	{
		psLOCAL->boShortPreamble = psBSS(psLOCAL->wConnectedSTAindex)->
										CapabilityInformation.Capability.ShortPreamble;
	}
	else
	{
		//if (psBSS(psLOCAL->wConnectedSTAindex)->DS_Parameter_Set.Current_Channel >14)
		//	psLOCAL->boShortPreamble = 0;
		//else
			psLOCAL->boShortPreamble = 0;
	}
	/*
	psLOCAL->bSlotTimeMode = 1;	//Long
	psLOCAL->boShortSlotTime = 0;
	hal_set_slot_time(&Adapter->sHwData, WLAN_SLOT_TIME_TYPE_LONG);
	*/
	if (!TS_RUNNING_IN_TESTSTA_MODE)
	{
		//Enforce to use short slot time in IBSS mode
		psLOCAL->bSlotTimeMode = 0;	//
		psLOCAL->boShortSlotTime = 1;
		hal_set_slot_time(&Adapter->sHwData, WLAN_SLOT_TIME_TYPE_SHORT);
	}
	//else
	//If it is in test mode, the slot time will be set by another command.

	hal_reset_counter( &Adapter->sHwData);
	psLOCAL->dwBasicRateBitmap = psSME->BasicRateBitmap;
	psLOCAL->dwSupportRateBitmap = psLOCAL->dwBasicRateBitmap | psSME->OpRateBitmap;
	TxRateHandler(Adapter);

	//invoke romaing task
	sRoamMsg.wMsgType = ROAMMSG_ROAM_REQ;
	sRoamMsg.pMsgPtr = NULL;
	Roam_Entry(Adapter, &sRoamMsg);
//#endif
}

void vSmeProc_JoinCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	K_MSG	sMsg;
	USHORT	i;

	//MLME_AUTHREQ_PARA sAuthReqPara;
	// Join in IBSS_NET also uses Start IBSS function, so h/w will not arise the 
	// syn. interrupt in IBSS_NET. 

	vSmeTimerStop(Adapter);
	// Join success, set BSS MLMEstate = STATE_1
	i=psSME->wDesiredJoinBSS;
	MLME_JoinCfm(psBSS(i), psBSS(i)->bBssType);
	//TODO: 1009
	if ( psBSS(i)->bBssType == ESS_NET)
	{
		// if (not DUTmode) auto start Authen-Req, send AuthenReq to MLME
		if ((psSME->boDUTmode != TRUE) || (psLOCAL->boHandover == TRUE))
		{
	    	// SME sent MLME_JoinReq to MLME, and MLME respond MLME_JoinCfm to SME
		    // In fact, MLME SM change its state.
			//--- prepare Authen_Req Message for sending to MLME
			sMsg.wMsgType = MLMEMSG_AUTH_REQ;
			sMsg.wInstance = psSME->wDesiredJoinBSS;
			psSME->boAuthRetryActive=FALSE;
			// _WKCHEN_NOTE1_
			sMsg.pMsgPtr = NULL;
			MLME_Entry(Adapter, &sMsg);
			SMEstate=AUTHENTICATE_PENDING;
		} 
		else 
		{
			SMEstate=JOIN_CFM;
		}
	}
	else
	{
		psLOCAL->wConnectedSTAindex = psSME->wDesiredJoinBSS;
		#ifdef _PE_STATE_DUMP_
		if (psLOCAL->NoOfJoinerInIbss != 1)
			WBDEBUG(("Fatal err of JoinerInIbss!!\n"));
		#endif
		//JoinerInIbss[0] has been used by peer STA firstly.
		psLOCAL->JoinerInIbss[1] = psLOCAL->JoinerInIbss[0];
		psLOCAL->JoinerInIbss[0] = (UCHAR)psLOCAL->wConnectedSTAindex;
		psLOCAL->NoOfJoinerInIbss = 2;

		psLOCAL->boHandover=FALSE;
		SMEstate=CONNECTED;
		vNetConnectIndicate(Adapter);

		//For IBSS rejoin
		psSME->IbssChan.band = psBSS(psLOCAL->wConnectedSTAindex)->band;
		psSME->IbssChan.ChanNo = 
					psBSS(psLOCAL->wConnectedSTAindex)->DS_Parameter_Set.Current_Channel;

		if (psLOCAL->CWMin == 255) // set according to 802.11 spec.
		{
		if (psBSS(psLOCAL->wConnectedSTAindex)->boERP)
			hal_set_cwmin(&Adapter->sHwData, 15);
		else
			hal_set_cwmin(&Adapter->sHwData, 31);
		}
		else
			hal_set_cwmin(&Adapter->sHwData, psLOCAL->CWMin);

		//Set H/W according to the new 11G settings
		//psLOCAL->boNonERPpresent = psBSS(psLOCAL->wConnectedSTAindex)->
		//										ERP_Information_Set.NonERP_Present;
		//psLOCAL->boProtectMechanism = psBSS(psLOCAL->wConnectedSTAindex)->
		//										ERP_Information_Set.Use_Protection;
		//TODO: protection mode setting
		//hal_set_protection_mode()
		if (psLOCAL->bPreambleMode == AUTO_MODE)
		{
			psLOCAL->boShortPreamble = psBSS(psLOCAL->wConnectedSTAindex)->
											CapabilityInformation.Capability.ShortPreamble;
		}
		else
		{
			//if (psBSS(psLOCAL->wConnectedSTAindex)->DS_Parameter_Set.Current_Channel >14)
			//	psLOCAL->boShortPreamble = 0;
			//else
				psLOCAL->boShortPreamble = 0;
		}
		/*
		psLOCAL->bSlotTimeMode = 1; //long
		psLOCAL->boShortSlotTime = 0;
		hal_set_slot_time(&Adapter->sHwData, WLAN_SLOT_TIME_TYPE_LONG);
		*/
		if (!TS_RUNNING_IN_TESTSTA_MODE)
		{
			//Enforce to use short slot time in IBSS mode
			psLOCAL->bSlotTimeMode = 0;	//
			psLOCAL->boShortSlotTime = 1;
			hal_set_slot_time(&Adapter->sHwData, WLAN_SLOT_TIME_TYPE_SHORT);
		}
		//else
		//If it is in test mode, the slot time will be set by another command.


		hal_reset_counter( &Adapter->sHwData);
		psLOCAL->dwBasicRateBitmap = psSME->BasicRateBitmap;
		psLOCAL->dwSupportRateBitmap = psSME->BasicRateBitmap | psSME->OpRateBitmap;
		TxRateHandler(Adapter);

		//invoke romaing task
		sMsg.wMsgType = ROAMMSG_ROAM_REQ;
		sMsg.pMsgPtr = NULL;
		Roam_Entry(Adapter, &sMsg);
	}
}

//Join Timeout
void vSmeProc_JoinFail(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	USHORT i;
	K_MSG	sSmeMsg;

	i=psSME->wDesiredJoinBSS;
	if (psBSS(i)->bBssType == ESS_NET)
	{
		hal_stop_sync_bss(&Adapter->sHwData);
		psLOCAL->boHandover=FALSE;
	}
	else
	{
		psLOCAL->NoOfJoinerInIbss = 0;
	}
	hal_join_request_stop(&Adapter->sHwData);
	MLME_initState(psBSS(i));
	SMEstate = SCAN_READY;
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("*********************** Join fail *************************\n"));
	#endif
	//After receiving a set SSID OID request in IBSS mode, if the join request fails,
	//we will start an IBSS.
	//It just likes the situation that we will start an IBSS if we can't find any peer
	//station.
	if (psSME->bDesiredBSSType == IBSS_NET)
	{
		sSmeMsg.wMsgType = SMEMSG_START_IBSS;
		sSmeMsg.pMsgPtr = NULL;
		SME_Entry(Adapter, &sSmeMsg);
	}
	// if exist candidate SSID then join next SSID
}

// ESS DUTmode only
void vSmeProc_AuthenReq(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	K_MSG	sMlmeMsg;

	// for DUTmode, GUI issue AuthenReq, send AuthenReq to MLME
	sMlmeMsg.wMsgType = MLMEMSG_AUTH_REQ;
	sMlmeMsg.wInstance = psSME->wDesiredJoinBSS;
	psSME->boAuthRetryActive=FALSE;
	// _WKCHEN_NOTE1_
	sMlmeMsg.pMsgPtr = NULL;
	MLME_Entry(Adapter, &sMlmeMsg);
	SMEstate=AUTHENTICATE_PENDING;
}

void vSmeProc_EssAuthenCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	UCHAR bResult;
	K_MSG sMlmeMsg;
//	MLME_AUTHREQ_PARA sAuthReqPara;

	bResult = *((UCHAR *)psMsg->pMsgPtr);
	if (bResult==MLME_SUCCESS)
	{
		vSmeTimerStop(Adapter); //
		SMEstate=AUTHENTICATED;
		if ((psSME->boDUTmode != TRUE) || (psLOCAL->boHandover == TRUE))
		{
			// send MLMEMSG_ASSOC_REQ to MLME
			if (psLOCAL->boHandover)
				sMlmeMsg.wMsgType = MLMEMSG_REASSOC_REQ;
			else
				sMlmeMsg.wMsgType = MLMEMSG_ASSOC_REQ;
			sMlmeMsg.wInstance = psSME->wDesiredJoinBSS;
			// Assoc parameter: Capability, Listen Interval, Support Rate are accessed by MLME
			// WKCHEN_NOTE1
			sMlmeMsg.pMsgPtr = NULL;
			MLME_Entry(Adapter, &sMlmeMsg);
		}
	}
	else if (bResult == RETRY)
	{
		// send MLMEMSG_AUTHEN_REQ to MLME
		sMlmeMsg.wMsgType = MLMEMSG_AUTH_REQ;
		sMlmeMsg.wInstance = psSME->wDesiredJoinBSS;
		// WKCHEN_NOTE1
		sMlmeMsg.pMsgPtr = NULL;
		MLME_Entry(Adapter, &sMlmeMsg);

		if (psSME->boAuthRetryActive!=TRUE)
		{
			vSmeTimerStart(Adapter,psSME->AuthenRetryTimerVal);
			psSME->boAuthRetryActive=TRUE;
		}
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("*********************** Auth fail/retry *************************\n"));
		#endif
	}
	else if (bResult==GIVE_UP)
	{
		vSmeTimerStop(Adapter);
		hal_stop_sync_bss(&Adapter->sHwData);
		SMEstate = SCAN_READY;
		psSME->boAuthRetryActive=FALSE;
		psLOCAL->boHandover=FALSE;
		//vNetDisconnectInd(Adapter);
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("*********************** Auth fail/give up *************************\n"));
		#endif
	}
}

void vSmeProc_AuthRetryTimeOut(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	hal_stop_sync_bss(&Adapter->sHwData);
	SMEstate=SCAN_READY;
	psSME->boAuthRetryActive=FALSE;
	// if (AuthenFail at Handover phase) then should Indicate 'DISCONNECT' to NDIS
	//vNetDisconnectInd(Adapter);
	psLOCAL->boHandover=FALSE;
}

void vSmeProc_AssocCfm(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	UCHAR bResult;
	K_MSG sRoamMsg;

	bResult = *((UCHAR *)psMsg->pMsgPtr);
	if (bResult == GIVE_UP)
	{
		hal_stop_sync_bss(&Adapter->sHwData);
		SMEstate = SCAN_READY;
		//vNetDisconnectInd(Adapter);
		psLOCAL->boHandover=FALSE;
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("************* Assoc fail *************\n"));
		#endif
	}
	else if (bResult==MLME_SUCCESS)
	{
		psLOCAL->wConnectedSTAindex = psSME->wDesiredJoinBSS;
		psLOCAL->boHandover=FALSE;
		SMEstate=CONNECTED;
		vNetConnectIndicate(Adapter);
		//11G TODO: only ERP element is existed, and then do the following.
		//Decide new 11G settings by AP

		//CWMin setting
		if (psLOCAL->CWMin == 255) // set according to 802.11 spec.
		{
		if (psBSS(psLOCAL->wConnectedSTAindex)->boERP)
			hal_set_cwmin(&Adapter->sHwData, 15);
		else
			hal_set_cwmin(&Adapter->sHwData, 31);
		}
		else
			hal_set_cwmin(&Adapter->sHwData, psLOCAL->CWMin);

		//Set H/W according to the new 11G settings
		psLOCAL->boNonERPpresent = psBSS(psLOCAL->wConnectedSTAindex)->
												ERP_Information_Set.NonERP_Present;
		psLOCAL->boProtectMechanism = psBSS(psLOCAL->wConnectedSTAindex)->
												ERP_Information_Set.Use_Protection;
		//TODO: protection mode setting
		//hal_set_protection_mode()
		if (psLOCAL->bPreambleMode == AUTO_MODE)
		{
			psLOCAL->boShortPreamble = psBSS(psLOCAL->wConnectedSTAindex)->
													CapabilityInformation.Capability.ShortPreamble;
		}
		else
		{
			//if (psBSS(psLOCAL->wConnectedSTAindex)->DS_Parameter_Set.Current_Channel >14)
			//	psLOCAL->boShortPreamble = 0;
				//else
				psLOCAL->boShortPreamble = 0;
		}
		if (psLOCAL->bSlotTimeMode == AUTO_MODE)
		{
			if (psBSS(psLOCAL->wConnectedSTAindex)->band == BAND_TYPE_OFDM_5)
				psLOCAL->boShortSlotTime = 1;
			else
				psLOCAL->boShortSlotTime = psBSS(psLOCAL->wConnectedSTAindex)->
											CapabilityInformation.Capability.Short_Slot_Time;
		}
		else
		{
			//if (psBSS(psLOCAL->wConnectedSTAindex)->DS_Parameter_Set.Current_Channel >14)
			//	psLOCAL->boShortSlotTime = 0;
				//else
				psLOCAL->boShortSlotTime = 0;
		}
		if (psLOCAL->boShortSlotTime == 1)
			hal_set_slot_time(&Adapter->sHwData, WLAN_SLOT_TIME_TYPE_SHORT);
		else
			hal_set_slot_time(&Adapter->sHwData, WLAN_SLOT_TIME_TYPE_LONG);

		hal_reset_counter( &Adapter->sHwData);
		psLOCAL->dwBasicRateBitmap = psSME->BasicRateBitmap;
		psLOCAL->dwSupportRateBitmap = psSME->BasicRateBitmap | psSME->OpRateBitmap;
		TxRateHandler(Adapter);

		//Invoke romaing task
		sRoamMsg.wMsgType = ROAMMSG_ROAM_REQ;
		sRoamMsg.pMsgPtr = NULL;
		Roam_Entry(Adapter, &sRoamMsg);
	}
	// NOTE: if (Retry Assoc) should start(AssocFailTimer);
}

void TxRateHandler(PWB32_ADAPTER Adapter)
{
	UCHAR	i,j;
	ULONG	Tmp;

	//convert bitmap to rates
	//basic rates
	j = 0;
	Tmp = 1;
	for (i=0 ; i<32; i++)
	{
		if ((Tmp & psLOCAL->dwBasicRateBitmap) != 0)
			psLOCAL->BRateSet[j++] = bBitmapToRate(i);
		Tmp	<<= 1;
	}
	psLOCAL->NumOfBRate = j;
	RateSort(psLOCAL->BRateSet, j, 1);

	//supported rates
	j = 0;
	Tmp = 1;
	for (i=0 ; i<32; i++)
	{
		if ((Tmp & psLOCAL->dwSupportRateBitmap) != 0)
			psLOCAL->SRateSet[j++] = bBitmapToRate(i);
		Tmp	<<= 1;
	}
	psLOCAL->NumOfSRate = j;
	RateReSortForSRate(Adapter, psLOCAL->SRateSet, j);

	//Channel 14 can't have any OFDM operations.
	if (psBSS(psLOCAL->wConnectedSTAindex)->DS_Parameter_Set.Current_Channel == 14)
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("psLOCAL->NumOfDsssRateInSRate=%d, psLOCAL->NumOfSRate=%d\n",
					 psLOCAL->NumOfDsssRateInSRate, psLOCAL->NumOfSRate));
		#endif
		if (psLOCAL->NumOfDsssRateInSRate < psLOCAL->NumOfSRate)
			psLOCAL->NumOfSRate =  psLOCAL->NumOfDsssRateInSRate;	//filter out OFDM rates
	}

	//For DTO
	MTO_SetDTORateRange(Adapter, psLOCAL->SRateSet, psLOCAL->NumOfSRate);

	if (psLOCAL->TxRateMode != RATE_AUTO)
	{
		if (psLOCAL->TxRateMode == RATE_MAX)
		{
			SetMaxTxRate(Adapter);
		}
		else
		{
			psLOCAL->CurrentTxRate = psLOCAL->TxRateMode;
			psLOCAL->CurrentTxFallbackRate = psLOCAL->CurrentTxRate;
		}
	}
}

void vSmeProc_AssocReq(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	K_MSG	sMlmeMsg;

	if (psSME->boDUTmode == TRUE)
	{
        //----- send MLMEMSG_ASSOC_REQ to MLME
		if (psLOCAL->boHandover) sMlmeMsg.wMsgType = MLMEMSG_REASSOC_REQ;
	    else sMlmeMsg.wMsgType = MLMEMSG_ASSOC_REQ;
	    sMlmeMsg.wInstance = psSME->wDesiredJoinBSS;
		// GUI supply the capability information, listen interval, current AP address,
		// SSID, supported rates
	    sMlmeMsg.pMsgPtr = NULL;
	    MLME_Entry(Adapter, &sMlmeMsg);
		// donot change state
    }
}

void vSmeProc_Disconnect(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	USHORT i;
	K_MSG	sMsg;

	i=psLOCAL->wConnectedSTAindex;
	if (psBSS(i)->bBssType == IBSS_NET)
	{
		hal_ibss_disconnect(&Adapter->sHwData);
		//update the MLME state of all BssDescription entries that belong to 
		//IBSS_NET to INACTIVE
		MLME_IBSSinitState(Adapter);
	}
	else
	{
		//send deauth frame
		sMsg.wMsgType = MLMEMSG_DEAUTH_REQ;
		sMsg.wInstance = i;
		sMsg.pMsgPtr = psMsg->pMsgPtr;	//reason: sending STA is leaving
		MLME_Entry(Adapter, &sMsg);//MLME state will be modified in MLME task
		ClearBSSdescpt(Adapter, i);
	}
	////////////////////////////////////////
	//Added by WangJS 2006.7.28
	#ifdef WB_LINUX
        FourWayClear(Adapter);	
        #endif
        Roam_ResetPara(Adapter);
	psLOCAL->wConnectedSTAindex = 0;
	psSME->wDesiredJoinBSS = 0;
//	sme_clear_all_mapping_key(Adapter); 20061017 remove
//	sme_clear_all_default_key(Adapter); 20061017 remove
	//#ifdef _WPA_
	psSME->pairwise_key_ok = 0;
	psSME->group_key_ok = 0;
	psSME->wpa_ok = 0;
	//#endif
	SMEstate = SCAN_READY;
	hal_stop_sync_bss(&Adapter->sHwData);
	vNetDisconnectInd(Adapter);
	psLOCAL->boHandover=FALSE;

	//To overcome the rejoin problem when using FUNK.
	//FUNK will not issue SSID again when disconnecting in IBSS mode.
	if (psSME->bDesiredBSSType == IBSS_NET)
	{
		//TODO : encryption ??
		sMsg.wMsgType = SMEMSG_JOIN_REQ;
		sMsg.wInstance = 0;
		sMsg.pMsgPtr = NULL;
		SME_Entry(Adapter, &sMsg);
	}
}

void vSmeProc_ReScan(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	//psSCAN->boSave = TRUE;
	psMsg->wMsgType=SCANMSG_SCAN_REQ;
	//psMsg->pMsgPtr =0;
	Scan_Entry(Adapter,psMsg);
}

//After scanning, should perform join request based on the
//current psSME->sDesiredXXX values
void vSmeProc_ScanThenJoin(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	psSME->boJoinReq = TRUE;
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("psSME->JoinReq == TRUE\n"));
	#endif
	psMsg->wMsgType=SCANMSG_SCAN_REQ;
	psMsg->pMsgPtr =0;
	Scan_Entry(Adapter,psMsg);
}

void vSmeProc_BgScan(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	psSCAN->boSave = TRUE;
	psMsg->wMsgType=SCANMSG_SCAN_REQ;
	psMsg->pMsgPtr = psMsg->pMsgPtr;	//scan request parameters
	Scan_Entry(Adapter,psMsg);
}

//Join request from user or ...
void vSmeProc_ManualHandoverJoin(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	K_MSG	sMsg;
	USHORT	reason;

	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: ManualHandover\n"));
	#endif
	//XP will set duplicated OID_802_11_SSID during a short time interval.
	//if (SMEstate == START_IBSS)
	if (psLOCAL->wConnectedSTAindex == 0)
	{
		if (boCmpSSID(&psSME->sDesiredSSID, &psBSS(psSME->wDesiredJoinBSS)->SSID) &&
			(psSME->bDesiredBSSType == psBSS(psSME->wDesiredJoinBSS)->bBssType))
		{
			if ((SMEstate != START_IBSS) || (psMsg->wInstance == 0 ))
			{
				//If this request is not filtered, then join self will happen.
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("*****  redundant join request(start IBSS) *****\n"));
				#endif
				//vNetConnectIndicate(Adapter);
				//The state is not CONNECTED, so should not indicate connected.
				return;
			}
			//In START_IBSS state, it may need to rejoin when receive probe resp. at different
			// channel(psMsg->wInstance != 0)
		}

		//need to perform re-joining
		if (psSME->bDesiredBSSType == IBSS_NET)
		{
			psLOCAL->NoOfJoinerInIbss = 0;
			MLME_initState(psBSS(psSME->wDesiredJoinBSS));//clear previous local descriptor
		}
	}
	else
	{
		//IN 2m_wlan_adhoc of HCT test, variation 9 has a particular OID sequence.
		//(When the redundant join comes, the connection may have failed but the state
		//is still CONNECT due to the roaming task checking.)
		//So, we don't prevent the redundant join request in IBSS mode.
		if (boCmpSSID(&psSME->sDesiredSSID, &psBSS(psLOCAL->wConnectedSTAindex)->SSID) &&
			//(psSME->bDesiredBSSType == psBSS(psLOCAL->wConnectedSTAindex)->bBssType) &&
			//(psSME->bDesiredBSSType == ESS_NET))
			(psSME->bDesiredBSSType == psBSS(psLOCAL->wConnectedSTAindex)->bBssType))
		{
			if( OS_MEMORY_COMPARE( psSME->abDesiredBSSID, "\xff\xff\xff\xff\xff\xff", MAC_ADDR_LENGTH ) )
			{
				#ifdef _PE_STATE_DUMP_
				WBDEBUG(("*****  redundant join request 1*****\n"));
				#endif
				vNetConnectIndicate(Adapter);
				return;//Redundant join request
			}
			else
			{
				if( OS_MEMORY_COMPARE( psSME->abDesiredBSSID, psBSS(psLOCAL->wConnectedSTAindex)->abBssID, MAC_ADDR_LENGTH ) )
				{
					#ifdef _PE_STATE_DUMP_
					WBDEBUG(("*****  redundant join request 2*****\n"));
					#endif
					vNetConnectIndicate(Adapter);
					return;//Redundant join request
				}
			}
		}
	}

	if (psLOCAL->wConnectedSTAindex != 0)
	{
		reason = 8;
		sMsg.wMsgType = MLMEMSG_DEAUTH_REQ;
		sMsg.wInstance = psLOCAL->wConnectedSTAindex;
		sMsg.pMsgPtr = &reason;	//reason: sending STA is leaving
		MLME_Entry(Adapter, &sMsg);//MLME state will be modified in MLME task

		//Don't clear WEP keys because the new key may has been set.
		//#ifdef _WPA_
		if ((psSME->bDesiredAuthMode == WPA_AUTH) ||
			(psSME->bDesiredAuthMode == WPAPSK_AUTH) ||
			(psSME->bDesiredAuthMode == WPANONE_AUTH)
			#ifdef _WPA2_
			||(psSME->bDesiredAuthMode == WPA2_AUTH)
			||(psSME->bDesiredAuthMode == WPA2PSK_AUTH)
            #endif //end def _WPA2_
            )
		{
			sme_clear_all_mapping_key(Adapter);
			sme_clear_all_default_key(Adapter);
			psSME->pairwise_key_ok = 0;
			psSME->group_key_ok = 0;
			psSME->wpa_ok = 0;
		}
		//#endif
		psLOCAL->boHandover = FALSE;
	}
	ClearOldData(Adapter);
	SMEstate = SCAN_READY;
	if (boJoinAction(Adapter) == 0)
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: Manual Join fail!\n"));
		#endif
		//Roam_ResetPara(Adapter); //reset(stop) roaming task no matter if it is active
		//psLOCAL->wConnectedSTAindex = 0;
		//SMEstate = SCAN_READY;	//???
		//CardSetAcceptBeacon(Adapter, FALSE);
		/*
		sScanMsg.wMsgType = SCANMSG_SCAN_REQ;
		sScanMsg.wInstance = 0;
		sScanMsg.pMsgPtr = NULL;
		Scan_Entry(Adapter,&sScanMsg);
		psSME->boJoinReq = TRUE;
		psSME->bJoinScanCount = 1;
		*/
	}
	else
	{
		/*
		psSME->boJoinReq = FALSE;
		psSME->bJoinScanCount = 0;
		*/
	}
}

//join request from roaming module, the candidate is known.
void vSmeProc_HandoverJoin(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	// if (Handover Join ok) SMEstate change to JOIN_PENDING and start(JoinFailTimer)
	// else SMEstate is CONNECTED, wait next JOIN_REQ
	psSME->wDesiredJoinBSS = *(USHORT *)(psMsg->pMsgPtr);
	//vRateToBitmap(Adapter, psSME->wDesiredJoinBSS);
	//psBSS(psSME->wDesiredJoinBSS)->boERP = boIsERPsta(Adapter, psSME->wDesiredJoinBSS);
	//11G TODO: Check basic rates, supported rates or other parameters to decide
	//			continue or not

	if (psSME->wState == CONNECTED)
	{
		psLOCAL->boHandover = TRUE;
		psLOCAL->wOldSTAindex = psLOCAL->wConnectedSTAindex;
		//ClearPendingPacket(Adapter);
		if (psSME->bDesiredAuthMode >= WPA_AUTH)
		{
			sme_clear_all_mapping_key(Adapter);
			sme_clear_all_default_key(Adapter);
			psSME->pairwise_key_ok = 0;
			psSME->group_key_ok = 0;
			psSME->wpa_ok = 0;
		}
		//ClearOldData(Adapter);
		//MLME_findSTA(psBSS(psLOCAL->wConnectedSTAindex));//update its state to IDLE_SCAN
		MLME_initState(psBSS(psLOCAL->wConnectedSTAindex));
	}
	psLOCAL->wConnectedSTAindex = 0;
	SMEstate=JOIN_PENDING;
	SetDesiredLocalRate(Adapter, psSME->wDesiredJoinBSS);
	psBSS(psSME->wDesiredJoinBSS)->boERP = boIsERPsta(Adapter, psSME->wDesiredJoinBSS);
	//not support PBCC
	psSME->wCapabilityInfo =
			psBSS(psSME->wDesiredJoinBSS)->CapabilityInformation.wValue & (~CAPABILITY_PBCC_BIT);
	vActiveHWMAC_join(Adapter); // include stop old sync and start new sync.
	vSmeTimerStart(Adapter,psSME->JoinFailTimerVal);
}

void vSmeProc_EndRoaming(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	Roam_ResetPara(Adapter);
	ClearBSSdescpt(Adapter, psSME->wDesiredJoinBSS);
	hal_stop_sync_bss(&Adapter->sHwData);
	vNetDisconnectInd(Adapter);
	SMEstate=SCAN_READY;
	//#ifdef _WPA_
	psSME->pairwise_key_ok = 0;
	psSME->group_key_ok = 0;
	psSME->wpa_ok = 0;
	//#endif
}

//Receive disconnect command from peer BSS
void vSmeProc_DeauthenInd(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	K_MSG	sRoamMsg;
	USHORT		EventValue;

	//driver inner disconnect, not really disconnect. Roaming task may try to re-scan
	//and re-connect the same BSS. So the WEP keys will not be cleared temporarily.

	//To avoid the previous supported/extended supported rate elements existing when
	// 11b and 11g mode exchange
	ClearBSSdescpt(Adapter, psMsg->wInstance);

	SMEstate=SCAN_READY;
	psSCAN->boSave = FALSE;
	psLOCAL->wConnectedSTAindex = 0;
	psLOCAL->boHandover=FALSE;

	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("!!! Rcv deauth/disassoc. frame, reason=%d\n", *(USHORT *)psMsg->pMsgPtr));
	#endif

	//suppose the value of reason will not excess 256
	EventValue = EVENT_RCV_DEAUTH | (*(UCHAR *)psMsg->pMsgPtr);
	FillEventLog(Adapter, EventValue);

	sRoamMsg.wMsgType = ROAMMSG_DEAUTHEN_IND;
	sRoamMsg.pMsgPtr = psMsg->pMsgPtr;	//Reason
	Roam_Entry(Adapter, &sRoamMsg);

	//Added by WangJS 2006.7.28
        //To clear all 4 way handshake of de-authentication
        #ifdef WB_LINUX
        FourWayClear(Adapter);
        #endif

}

/*	//This function is the same as vSmeProc_DeauthenInd()
void vSmeProc_DisassocInd(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	// may back to AUTHENTICATED state and retry ASSOC_REQ
	psLOCAL->wConnectedSTAindex = 0;
	psLOCAL->boHandover=FALSE;
	SMEstate=SCAN_READY;
	CardStopSyncWithBSS(Adapter);	// not sure ???
	vNetDisconnectInd(Adapter);
}
*/

void vSmeProc_IbssAuth(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	// IBSS authen another STA , note pass parameters (DUT only)
	K_MSG	sMlmeMsg;
	USHORT  	wSTAidx;
//	MLME_AUTHREQ_PARA sAuthReqPara;

	wSTAidx=psLOCAL->wConnectedSTAindex;
	if (psBSS(wSTAidx)->bBssType == IBSS_NET)
	{
		if ((wSTAidx=wBSSfindMACaddr(Adapter, (UCHAR *)((MLME_AUTHREQ_PARA*)(psMsg->pMsgPtr))->peerMACaddr))==0)
			return; // no IBSS found
		sMlmeMsg.wMsgType = MLMEMSG_AUTH_REQ;
		sMlmeMsg.wInstance = wSTAidx;
		psSME->boAuthRetryActive=FALSE;
		// WKCHEN_NOTE1
		sMlmeMsg.pMsgPtr = psMsg->pMsgPtr;
		MLME_Entry(Adapter, &sMlmeMsg);
		//SMEstate=CONNECTED;
	}
}
#ifdef _WAIT_REMOVE_
void vSmeProc_IBSSJoinUpdateBSSID(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	USHORT PeerIdx;
	//Configure the desired BSSID and enable join request 
	//to rejoin the merging IBSS
	//stop tx beacon
/*
	if (boJoinAction(Adapter) != 0)
	{
		//SMEstate=JOIN_PENDING;
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: IBSS merge.....\n"));
		#endif
	}
*/
	PeerIdx = *(USHORT *)(psMsg->pMsgPtr);
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: IBSS merge, bss_idx = %x\n", PeerIdx));
	#endif
	if (psLOCAL->wConnectedSTAindex !=0)
	{
		psSME->wDesiredJoinBSS = psLOCAL->wConnectedSTAindex;
		MLME_findSTA(psBSS(psSME->wDesiredJoinBSS));
	}
	OS_MEMORY_COPY( psBSS(psSME->wDesiredJoinBSS), psBSS(PeerIdx), sizeof(WB_BSSDESCRIPTION) );
	//The state of psBSS(wNewIndex) is IDLE_SCAN, copy from psBSS(wDscptIndex)
	// update LocalMACaddr,...etc
	//11G TODO: some parameters also need to be modified, such as supported
	//			rates, capability, ..
	((PMACADDR)psBSS(psSME->wDesiredJoinBSS)->abPeerAddress)->ll = ((PMACADDR)psLOCAL->ThisMacAddress)->ll;
	((PMACADDR)psBSS(psSME->wDesiredJoinBSS)->abPeerAddress)->ss = ((PMACADDR)psLOCAL->ThisMacAddress)->ss;
	*(USHORT *)(psMsg->pMsgPtr) = psSME->wDesiredJoinBSS;
	vSmeProc_HandoverJoin(Adapter, psMsg);

}
#endif
/*
void vSmeProc_IbssWaitAuthTimeout(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	//The peer STA doesn't need auth, so connect
	psLOCAL->wConnectedSTAindex = wDscptIndex;

	if (SMEstate!=CONNECTED)
	{
		vNetConnectIndicate(Adapter);
		
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("STATE: IBSS connect confirm\n"));
		#endif
	}
	SMEstate=CONNECTED;

	for (i=0; i<psLOCAL->NonERPSupportedRatesElement.Length; i++)
	{
		if (psLOCAL->NonERPSupportedRatesElement.SupportedRates[i]&0x80)
			psLOCAL->dwBasicRateBitmap |=
				(1<<bRateToBitmapIndex(Adapter, psLOCAL->NonERPSupportedRatesElement.SupportedRates[i]&0x7f));
		//else
			psLOCAL->dwOperationalRateBitmap |=
				(1<<bRateToBitmapIndex(Adapter, psLOCAL->NonERPSupportedRatesElement.SupportedRates[i]&0x7f));
	}

	//decide the max tx rate
	BitMap = psLOCAL->dwOperationalRateBitmap & 
				(psBSS(psLOCAL->wConnectedSTAindex)->dwOperationalRateBitmap);
	for (BitIndex=0 ; BitIndex<32; BitIndex++)
	{
		BitMap	>>= 1;
		if (BitMap == 0)
			break;
	}
	Adapter->Mds.CurrentTxRate = bBitmapToRate(BitIndex);

	//invoke romaing task
	sRoamMsg.wMsgType = ROAMMSG_ROAM_REQ;
	sRoamMsg.pMsgPtr = NULL;
	Roam_Entry(Adapter, &sRoamMsg);
}
*/
//---------------- WPA Countermeasure --------------------------
void vSmeProc_CountermeaureCancel(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	Adapter->Mds.bMICfailCount = 0;
}

void vSmeProc_CountermeasureBlockCancel(PWB32_ADAPTER Adapter, pK_MSG psMsg)
{
	Adapter->Mds.bMICfailCount = 0;
	Adapter->Mds.boCounterMeasureBlock = 0;
}


//---------------- POWER MANAGEMENT ----------------------------
void vSmeProc_PowerSaveReq(PWB32_ADAPTER Adapter,pK_MSG psMsg)
{
	UCHAR	PsMode;

	PsMode = *(UCHAR *)(psMsg->pMsgPtr);
    if (PsMode == PWR_ACTIVE)
    {
        // Force to enter power active mode.
   	    // The HW-MAC shall change to power active mode and then try to
   	    // transmit a NULL frame with PWRMgt bit of the Frame control field = 0.
		hal_set_power_save_mode(&Adapter->sHwData,
       			                FALSE,	//POWER_ACTIVE
           	    		        FALSE,
               	        		FALSE);	//DTIM doesn't WAKE UP
		psLOCAL->iPowerSaveMode = PWR_ACTIVE;	//We can make sure H/W mac will be active
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("enter power active\n"));
		#endif
    }
    else
    {
		//if (psLOCAL->iPowerSaveMode != PWR_SAVE)
		{
         	// Try to enter power save mode.
			hal_set_power_save_mode(&Adapter->sHwData,
    	    		                TRUE,	//POWER_SAVE
        	        		        FALSE,
            	            		TRUE);	//DTIM WAKE UP
			//psLOCAL->iPowerSaveMode = PWR_SAVE;	//We can't make sure H/W mac will be sleep
													//The setting may fail.
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("enter power save\n"));
			#endif
		}
	}
}

CHAR SendNullData(PWB32_ADAPTER Adapter, UCHAR PowerMode)
{
	PUCHAR	msg;
	struct Data_Frame* msgHeader;
	USHORT	wConnectIdx;

	if ((msg=MLMEGetMMPDUBuffer(Adapter))==NULL)
	{
		Adapter->sMlmeFrame.wNumTxMMPDUDiscarded++;
		return -1;  // fail get free msg buffer
	}
	wConnectIdx = psLOCAL->wConnectedSTAindex;
	msgHeader = (struct Data_Frame *) &msg[0];

	// setup Frame-Header subfields
	msgHeader->frame_control.mac_frame_info = MAC_SUBTYPE_DATA_NULL;
	if (psBSS(wConnectIdx)->bBssType == ESS_NET)
	    msgHeader->frame_control.to_ds      = 1;
	else
	    msgHeader->frame_control.to_ds      = 0;
    msgHeader->frame_control.from_ds    = 0;
	msgHeader->frame_control.more_frag 	= 0;
    msgHeader->frame_control.retry      = 0;
	msgHeader->frame_control.more_data 	= 0;
    msgHeader->frame_control.order      = 0;
	if (PowerMode  == PWR_SAVE)
	    msgHeader->frame_control.pwr_mgt    = 1;
	else
    	msgHeader->frame_control.pwr_mgt    = 0;
    msgHeader->frame_control.WEP        = 0;
    msgHeader->duration                 = 0;    // Set by the MDS
	
    OS_MEMORY_COPY( msgHeader->Addr1, psBSS(Adapter->sLocalPara.wConnectedSTAindex)->abBssID, MAC_ADDR_LENGTH );
	OS_MEMORY_COPY( msgHeader->Addr2, Adapter->sLocalPara.ThisMacAddress, MAC_ADDR_LENGTH );
	OS_MEMORY_COPY( msgHeader->Addr3, psBSS(Adapter->sLocalPara.wConnectedSTAindex)->abBssID, MAC_ADDR_LENGTH );
	// FrameSequenceNumber is generated by HW-MAC

    // now send this message out
	if (1 == MLMESendFrame( Adapter,
					(UCHAR *) &msg[0],
					//sizeof(struct Data_Frame) - 6,
					sizeof(struct Data_Frame) ,
					FRAME_TYPE_802_11_DATA))
        return 1;                           // Has sent to the Tx handler.
	else
	{
		//return MLME buffer
		MLMEfreeMMPDUBuffer(Adapter, msg);
		return -1;
	}

}


//-----   For H/W query/set callback functions   ------------
void UpdateBssidFromHw(PWB32_ADAPTER Adapter)
{
	psLOCAL->HwBssidValid = TRUE;

	if (psLOCAL->wConnectedSTAindex != 0)
	{
		//make the bssid stored in S/W and H/W can be consistent.
		if (boCmpMacAddr( psBSS(psLOCAL->wConnectedSTAindex)->abBssID, psLOCAL->HwBssid) == 0) //not equal
		{
			OS_MEMORY_COPY( psBSS(psLOCAL->wConnectedSTAindex)->abBssID, psLOCAL->HwBssid, MAC_ADDR_LENGTH );
			#ifdef _PE_STATE_DUMP_
			WBDEBUG(("** H/W BSSID has been changed. **\n"));
			WBDEBUG(("read BSSID=%x-%x-%x-%x-%x-%x\n",
						psLOCAL->HwBssid[0],psLOCAL->HwBssid[1],psLOCAL->HwBssid[2],
						psLOCAL->HwBssid[3],psLOCAL->HwBssid[4],psLOCAL->HwBssid[5]));
			#endif

		}
	}
}

void GetMacPsStateComplete(PWB32_ADAPTER Adapter)
{
	psLOCAL->boMacPsValid = TRUE;
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("!!psLOCAL->iPowerSaveMode = %d\n", psLOCAL->iPowerSaveMode));
	#endif
}

void HwSetChanComplete(PWB32_ADAPTER Adapter, ChanInfo Chan)
{
	psLOCAL->CurrentChan = Chan;
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("--- Set chan complete, ChanNo = %d, band =%d \n",
						 psLOCAL->CurrentChan.ChanNo, psLOCAL->CurrentChan.band));
	#endif
}

//-----   Supported Channels   ------------
void UNKNOWN_ChanRange(PWB32_ADAPTER Adapter, UCHAR PhyType, psCHAN_LIST psChanList)
{
	UCHAR	i,j;

	j = 0;
	switch(PhyType)
	{
		case RF_MAXIM_2827:
		case RF_MAXIM_2828:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=1; i<=LOCAL_UNKNOWN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				case MODE_802_11_A:
					for (i=0; i<8; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_5;
						if (i < 8)
							psChanList->Channel[j++].ChanNo = (i+9)*4;
						// H/W doesn't support
						//else
						//	psChanList->Channel[j++].ChanNo = (i+17)*4;
					}
					psChanList->Count = j;
					break;

				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=1; i<=LOCAL_UNKNOWN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_UNKNOWN_24_CHANNEL_NUM;
					break;
			}
			break;
		case RF_MAXIM_2829:
		case RF_AIROHA_7230:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=1; i<=LOCAL_UNKNOWN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				case MODE_802_11_A:
					for (i=0; i<LOCAL_UNKNOWN_5_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_5;
						if (i < 3)
							psChanList->Channel[j++].ChanNo = i*4 + 8;	// 8 ~ 16
						else if (i < 10)
							psChanList->Channel[j++].ChanNo = i*2 + 28;	// 34 ~ 46
						else if (i < 15)
							psChanList->Channel[j++].ChanNo = i*4 + 8;	// 48 ~ 64
						else if (i < 26)
							psChanList->Channel[j++].ChanNo = i*4 + 40;	// 100 ~ 140
						else if (i < 30)
							psChanList->Channel[j++].ChanNo = i*4 + 45;	// 149 ~ 161, not include 165
						else if (i < 34)
							psChanList->Channel[j++].ChanNo = i*4 + 64; // 184 ~ 196
					}
					psChanList->Count = j;
					break;
				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=1; i<=LOCAL_UNKNOWN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_UNKNOWN_24_CHANNEL_NUM;
					break;
			}
			break;

		case RF_MAXIM_2825:
		case RF_AIROHA_2230:
		case RF_AIROHA_2230S: // 20060420 Add this
		case RF_WB_242:
		case RF_WB_242_1: // 20060619.5 Add
		default:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				default:
					for (i=1; i<=LOCAL_UNKNOWN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_UNKNOWN_24_CHANNEL_NUM;
					break;
			}
			break;
	}
}

void EUROPE_ChanRange(PWB32_ADAPTER Adapter, UCHAR PhyType, psCHAN_LIST psChanList)
{
	UCHAR	i,j;

	j = 0;
	switch(PhyType)
	{
		case RF_MAXIM_2827:
		case RF_MAXIM_2828:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=1; i<=LOCAL_EUROPE_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				case MODE_802_11_A:
					for (i=0; i<LOCAL_EUROPE_5_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_5;
						if (i < 8)
							psChanList->Channel[j++].ChanNo = (i+9)*4;
						// H/W doesn't support
						//else
						//	psChanList->Channel[j++].ChanNo = (i+17)*4;
					}
					psChanList->Count = j;
					break;

				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=1; i<=LOCAL_EUROPE_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_EUROPE_24_CHANNEL_NUM;
					break;
			}
			break;
		case RF_MAXIM_2829:
		case RF_AIROHA_7230:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=1; i<=LOCAL_EUROPE_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				case MODE_802_11_A:
					for (i=0; i<LOCAL_EUROPE_5_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_5;
						if (i < 8)
							psChanList->Channel[j++].ChanNo = (i+9)*4;
						else
							psChanList->Channel[j++].ChanNo = (i+17)*4;
					}
					psChanList->Count = j;
					break;
				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=1; i<=LOCAL_EUROPE_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_EUROPE_24_CHANNEL_NUM;
					break;
			}
			break;

		case RF_MAXIM_2825:
		case RF_AIROHA_2230:
		case RF_AIROHA_2230S: // 20060420 Add this
		case RF_WB_242:
		case RF_WB_242_1: // 20060619.5 Add
		default:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				default:
					for (i=1; i<=LOCAL_EUROPE_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_EUROPE_24_CHANNEL_NUM;
					break;
			}
			break;
	}
}

void JAPAN_ChanRange(PWB32_ADAPTER Adapter, UCHAR PhyType, psCHAN_LIST psChanList)
{
	UCHAR	i,j;

	j = 0;
	switch(PhyType)
	{
		case RF_MAXIM_2827:
		case RF_MAXIM_2828:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=1; i<=LOCAL_JAPAN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				case MODE_802_11_A:
					for (i=0; i<LOCAL_JAPAN_5_CHANNEL_NUM; i++)
					{
						//H/W doesn't support
						//psChanList->Channel[j].band = BAND_TYPE_OFDM_5;
						//if (i < 3)
						//	psChanList->Channel[j++].ChanNo = i*4 + 8;
						//else if (i < 7)
						//	psChanList->Channel[j++].ChanNo = i*4 + 22;
						//else
						//	psChanList->Channel[j++].ChanNo = i*4 +156;
					}
					psChanList->Count = j;
					break;

				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=1; i<=(LOCAL_JAPAN_24_CHANNEL_NUM); i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_JAPAN_24_CHANNEL_NUM;
					break;
			}
			break;
		case RF_MAXIM_2829:
		case RF_AIROHA_7230:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=1; i<=LOCAL_JAPAN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				case MODE_802_11_A:
					for (i=0; i<LOCAL_JAPAN_5_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_5;
						if (i < 3)
							psChanList->Channel[j++].ChanNo = i*4 + 8;
						else if (i < 7)
							psChanList->Channel[j++].ChanNo = i*4 + 22;
						else
							psChanList->Channel[j++].ChanNo = i*4 +156;
					}
					psChanList->Count = j;
					break;
				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=1; i<=LOCAL_JAPAN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_JAPAN_24_CHANNEL_NUM;
					break;
			}
			break;
		case RF_MAXIM_2825:
		case RF_AIROHA_2230:
		case RF_AIROHA_2230S: // 20060420 Add this
		case RF_WB_242:
		case RF_WB_242_1: // 20060619.5 Add
		default:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				default:
					for (i=1; i<=LOCAL_JAPAN_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_JAPAN_24_CHANNEL_NUM;
					break;
			}
			break;
	}
}

void USA_ChanRange(PWB32_ADAPTER Adapter, UCHAR PhyType, psCHAN_LIST psChanList)
{
	UCHAR	i,j;

	j = 0;
	switch(PhyType)
	{
		case RF_MAXIM_2827:
		case RF_MAXIM_2828:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=1; i<=LOCAL_USA_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				case MODE_802_11_A:
					for (i=0; i<LOCAL_USA_5_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_5;
						if (i < 8)
							psChanList->Channel[j++].ChanNo = (i+9)*4;
						// H/W doesn't support
						//else
						//	psChanList->Channel[j++].ChanNo = (i+29)*4+1;
					}
					psChanList->Count = j;
					break;

				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=1; i<=LOCAL_USA_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_USA_24_CHANNEL_NUM;
					break;
			}
			break;
		case RF_MAXIM_2829:
		case RF_AIROHA_7230:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=1; i<=LOCAL_USA_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				case MODE_802_11_A:
					for (i=0; i<LOCAL_USA_5_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_5;
						if (i < 8)
							psChanList->Channel[j++].ChanNo = (i+9)*4;
						else
							psChanList->Channel[j++].ChanNo = (i+29)*4+1;
					}
					psChanList->Count = j;
					break;
				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=1; i<=LOCAL_USA_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_USA_24_CHANNEL_NUM;
					break;
			}
			break;
		case RF_MAXIM_2825:
		case RF_AIROHA_2230:
		case RF_AIROHA_2230S: // 20060420 Add this
		case RF_WB_242:
		case RF_WB_242_1: // 20060619.5 Add
		default:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				default:
					for (i=1; i<=LOCAL_USA_24_CHANNEL_NUM; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					psChanList->Count = LOCAL_USA_24_CHANNEL_NUM;
					break;
			}
			break;
	}
}

//---------------------
void SPAIN_ChanRange(PWB32_ADAPTER Adapter, UCHAR PhyType, psCHAN_LIST psChanList)
{
	USHORT	ChannelCount;
	UCHAR	i,j;

	j = 0;
	switch(PhyType)
	{
		case RF_MAXIM_2827:
		case RF_MAXIM_2828:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=10; i<=11; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				//case MODE_802_11_A:
					ChannelCount = j;
					break;

				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=10; i<=11; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 2;
					break;
			}
			break;
		case RF_MAXIM_2829:
		case RF_AIROHA_7230:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=10; i<=11; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				//case MODE_802_11_A:
					ChannelCount = j;
					break;
				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=10; i<=11; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 2;
					break;
			}
			break;
		case RF_MAXIM_2825:
		case RF_AIROHA_2230:
		case RF_AIROHA_2230S: // 20060420 Add this
		case RF_WB_242:
		case RF_WB_242_1: // 20060619.5 Add
		default:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				default:
					for (i=10; i<=11; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 2;
					break;
			}
			break;
	}

	OS_MEMORY_COPY( &(psChanList->Count), &ChannelCount, sizeof(USHORT) );
}

void FRANCE_ChanRange(PWB32_ADAPTER Adapter, UCHAR PhyType, psCHAN_LIST psChanList)
{
	USHORT	ChannelCount;
	UCHAR	i,j;

	j = 0;
	switch(PhyType)
	{
		case RF_MAXIM_2827:
		case RF_MAXIM_2828:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=10; i<=13; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				//case MODE_802_11_A:
					ChannelCount = j;
					break;

				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=10; i<=13; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 4;
					break;
			}
			break;
		case RF_MAXIM_2829:
		case RF_AIROHA_7230:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=10; i<=13; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				//case MODE_802_11_A:
					ChannelCount = j;
					break;
				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=10; i<=13; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 4;
					break;
			}
			break;
		case RF_MAXIM_2825:
		case RF_AIROHA_2230:
		case RF_AIROHA_2230S: // 20060420 Add this
		case RF_WB_242:
		case RF_WB_242_1: // 20060619.5 Add
		default:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				default:
					for (i=10; i<=13; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 4;
					break;
			}
			break;
	}

	OS_MEMORY_COPY( &(psChanList->Count), &ChannelCount, sizeof(USHORT) );
}

void ISRAEL_ChanRange(PWB32_ADAPTER Adapter, UCHAR PhyType, psCHAN_LIST psChanList)
{
	USHORT	ChannelCount;
	UCHAR	i,j;

	j = 0;
	switch(PhyType)
	{
		case RF_MAXIM_2827:
		case RF_MAXIM_2828:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=3; i<=9; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				//case MODE_802_11_A:
					ChannelCount = j;
					break;

				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=3; i<=9; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 7;
					break;
			}
			break;
		case RF_MAXIM_2829:
		case RF_AIROHA_7230:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				case MODE_802_11_ABG:
					for (i=3; i<=9; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
				//case MODE_802_11_A:
					ChannelCount = j;
					break;
				case MODE_802_11_BG:
				case MODE_802_11_BG_IBSS:
				case MODE_802_11_B:
				default:
					for (i=3; i<=9; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 7;
					break;
			}
			break;
		case RF_MAXIM_2825:
		case RF_AIROHA_2230:
		case RF_AIROHA_2230S: // 20060420 Add this
		case RF_WB_242:
		case RF_WB_242_1: // 20060619.5 Add
		default:
			switch (psLOCAL->bMacOperationMode)
			{
				case MODE_AUTO:
				default:
					for (i=3; i<=9; i++)
					{
						psChanList->Channel[j].band = BAND_TYPE_OFDM_24;
						psChanList->Channel[j++].ChanNo = i;
					}
					ChannelCount = 7;
					break;
			}
			break;
	}

	OS_MEMORY_COPY( &(psChanList->Count), &ChannelCount, sizeof(USHORT) );
}




//---------------------

//Decide the supported channels
void GetSupportChanRange(PWB32_ADAPTER Adapter)
{
	UCHAR PhyType;

	hal_get_phy_type(&Adapter->sHwData, &PhyType);
	switch (psLOCAL->region)
	{
		case REGION_EUROPE:
			EUROPE_ChanRange(Adapter, PhyType, &(psLOCAL->sSupportChanList));
			break;
		case REGION_JAPAN:
			JAPAN_ChanRange(Adapter, PhyType, &(psLOCAL->sSupportChanList));
			break;
		case REGION_UNKNOWN:
			UNKNOWN_ChanRange(Adapter, PhyType, &(psLOCAL->sSupportChanList));
			break;
		case REGION_FRANCE:
			FRANCE_ChanRange(Adapter, PhyType, &(psLOCAL->sSupportChanList));
			break;
		case REGION_SPAIN:
			SPAIN_ChanRange(Adapter, PhyType, &(psLOCAL->sSupportChanList));
			break;
		case REGION_ISRAEL:
			ISRAEL_ChanRange(Adapter, PhyType, &(psLOCAL->sSupportChanList));
			break;
		case REGION_USA:
		//case REGION_CANADA:
		default:
			USA_ChanRange(Adapter, PhyType, &(psLOCAL->sSupportChanList));
			break;
	}
}

//Decide the channel of start IBSS
void GetIbssChan(PWB32_ADAPTER Adapter)
{
	UCHAR	i;

	//Decide the IBSS channel
	if (Adapter->sLocalPara.IbssChanSetting.ChanNo != 0)	//Not Auto
	{
		for (i=0; i<psLOCAL->sSupportChanList.Count; i++)
		{
			if ((psLOCAL->IbssChanSetting.band == psLOCAL->sSupportChanList.Channel[i].band) &&
				(psLOCAL->IbssChanSetting.ChanNo == psLOCAL->sSupportChanList.Channel[i].ChanNo))
				break;// channel setting from registry or wwu is included in supported channel list
		}
		if (i != psLOCAL->sSupportChanList.Count)
		{
			psSME->IbssChan = psLOCAL->IbssChanSetting;
			return;
		}
	}

	//Auto, select the first one
	psSME->IbssChan = psLOCAL->sSupportChanList.Channel[0];
}

//Record into log
void FillEventLog(PWB32_ADAPTER Adapter, USHORT EventValue)
{
	//Record into log
	//BYTE 3~2 : count, BYTE 1 : Event, BYTE 0 : reason
	psLOCAL->EventLog.EventValue[psLOCAL->EventLog.index] =
				(psLOCAL->EventLog.Count<<16) | EventValue;

	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("--- Add event log: count =%x, index =%x, value =%x\n",
							psLOCAL->EventLog.Count+1,
							psLOCAL->EventLog.index,
							psLOCAL->EventLog.EventValue[psLOCAL->EventLog.index]));
	#endif

	if ((++psLOCAL->EventLog.index) >= 64)
		psLOCAL->EventLog.index = 0;
	psLOCAL->EventLog.Count++;
}

VOID CheckHwRadioStatus( IN PWB32_ADAPTER Adapter )
{
	RadioOff DesiredRadioOffData, CurrentRadioOffData;

	DesiredRadioOffData.boHwRadioOff = hal_get_hw_radio_off( &Adapter->sHwData );
	if (DesiredRadioOffData.boHwRadioOff != psLOCAL->RadioOffStatus.boHwRadioOff)
	{
		// H/W radio mode had been changed
		DesiredRadioOffData.boSwRadioOff = psLOCAL->RadioOffStatus.boSwRadioOff;
		CurrentRadioOffData = psLOCAL->RadioOffStatus;
		CheckRadioOffForDisassoc( Adapter, DesiredRadioOffData, CurrentRadioOffData);
		sme_set_radio_mode(Adapter, DesiredRadioOffData);
	}
}

//check whether it needs to disassoc.
VOID CheckRadioOffForDisassoc( IN PWB32_ADAPTER Adapter,
								RadioOff DesiredRadioOffData,
								RadioOff CurrentRadioOffData )
{
	UCHAR	boDesiredRadioOff, boCurrentRadioOff;

	if ((DesiredRadioOffData.boHwRadioOff == TRUE) || (DesiredRadioOffData.boSwRadioOff == TRUE))
		boDesiredRadioOff = TRUE;
	else
		boDesiredRadioOff = FALSE;

	if ((CurrentRadioOffData.boHwRadioOff == TRUE) || (CurrentRadioOffData.boSwRadioOff == TRUE))
		boCurrentRadioOff = TRUE;
	else
		boCurrentRadioOff = FALSE;

	if ((boDesiredRadioOff != boCurrentRadioOff) && (boDesiredRadioOff == TRUE))
		sme_set_disassociate(Adapter);
}


